Udemy logo

bubblesortjavaSpring MVC is perfect for building simple but powerful Java Web applications. It provides a framework which contains a wide range of configurable components depending on what kind of web application you are attempting to build.

When you are getting started with Spring MVC it can all sound rather daunting and complicated. However, creating an application from scratch is not that difficult. To get the most out of this tutorial it’s best that you have at least basic knowledge in building Java Web applications, as these methods can only be applied after the Spring MVC controller has been able to complete the execution you have created. If you are a complete beginner, then there is no need to panic. There are still plenty of ways you can learn about Java from scratch quickly and easily so then you can pursue whatever project you have in mind.

Making A Start With Spring MVC

An MVC (Model View Controller) is a design pattern that has become a popular tool when designing web applications. It has the ability to organize all the information in the application and place them into three groups; transformations of data, representation of data, and data.

When it comes to a Spring MVC application, the controller method works with the application when it is triggered into action when an HTTP request is made by a browser. This then produces and names a view which shows the user how the data should be presented to them. It also creates a model that represents some of the data. At this point, if you are planning of using Spring MVC but have had no experience with it to date, then it could be a good idea to learn a little more about Spring MVC and how it works before you make a start on building your web application.

A Spring MVC application is considered to be rather traditional in that it uses the Java Web Application structure. Within the WEB-INF directory there is an optional directory that houses library dependencies along with an optional classes directory which houses compiled Java classes. While these are optional files they can be utilized with great effect. As you will see at the end of the piece, these files and directories can help keep your completed application organized and running smoothly without requiring too much maintenance.

Spring is configured using DispatcherServlet, which is what is referred to as the Front Controller. It is put into action by a Java Web application server based on whatever form of configuration has been put in place in web.xml. DispatcherServlet has to be set so then it can use what is known as an AnnotationConfigWebApplicationContext so then you can enable Java configuration. You also need to make sure that the action is directed to the Java configuration class. This can be achieved by using a code similar to the one below:

<servlet>
     <servlet-name>spring-mvc</servlet-name>
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     <init-param>
       <param-name>contextClass</param-name>
       <param-value>org.springframework.web.context.support.AnnotationConfigWebApplication
       Context</param-value>
     </init-param>
     <init-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>bootstrap.ApplicationConfiguration</param-value>
     </init-param>
   </servlet>
   <servlet-mapping>
     <servlet-name>spring-mvc</servlet-name>
     <url-pattern>/</url-pattern>
   </servlet-mapping>

In the past, when it came to developing a Spring based application it meant working almost exclusively with XML configuration. Thankfully for many people that is now a thing of the past, as XML proves to be rather difficult to maintain and rather fragile. Even the slightest change to data could have resulted in hours trying to maintain the application, only to discover that your minor change has broken it. In the more recent versions of Spring, Java has taken over most of the configuration burden from XML, with more and more responsibility being handed over to Java with every version. This naturally has been met with a very positive response from users who are hoping to migrate entirely away from the XML configuration. Spring 3.1 can be used with full support from Java.

A Spring Java configuration class has rather clear annotations within the code, making it a lot easier for the user to read, understand, and implement. @Configuration and @Bean are the two main parts of the application that build up the components. @EnableWebMvc enables the infrastructure on the configuration class.

The form of configuration you see in the code below contains four beans, all of which play a vital role. Two Spring MVC controllers are present to create root-level and comment-specific endpoints. These areas are important when it comes time to address the condition of the backend of the web application. There is also a Spring MVC view resolver which provides JSP views, which is something we will address in greater detail later in the article. Finally, there is also a commentsService which is a service-layer class that is designed to provide easy access to the application data. There will also be some tips on how to organize the web application’s data in different models later.

@EnableWebMvc
   @Configuration
   public class ApplicationConfiguration {
     @Bean
     public CommentsService commentsService() {
       return new InMemCommentsService();
     }
     @Bean
     public IndexController indexController() {
       return new IndexController();
     }
     @Bean
     public CommentsController commentsController() {
       return new CommentsController();
     }
     @Bean
     public ViewResolver viewResolver() {
       InternalResourceViewResolver jspViewResolver = new InternalResourceViewResolver();
       jspViewResolver.setPrefix("/WEB-INF/views/");
       jspViewResolver.setSuffix(".jsp");
       return jspViewResolver;
     }
   }

Next we need to configure the controllers. They are an important part of Spring MVC as they are responsible for bringing the HTTP endpoints together so then it is readable as application logic. In effect they take the information being provided and make it actionable within the web application. It has the exact same effect of pressing a button on a controller when playing on a video game: the controller takes the information you have entered by pressing a specific button and turns it into a specific action that you see on the computer screen.

The bindings that are created by the controller are configured through @RequestMapping-annotated methods in a @Controller-annotated class. As you can see below, because of the simplicity of Java these bindings can be configured with a rather short code.

@Controller
   @RequestMapping("/")
   public class IndexController {
     @RequestMapping(method = RequestMethod.GET)
     public String getIndex() {
       return "redirect:comments";
     }
   }

When it comes to IndexController, it becomes a little simpler still. A @RequestMapping-annotated method is all that is required to connect the root URI for HTTP GET requests to a view that’s known as redirect:comments. This essentially means that a convention is built right into the very heart of the Spring application to send an HTTP redirect straight to the user for the URI/comments. This is quite a useful part of the application as it combines more elements together, and makes it easier to configure and change parts of the application in the future.

@RequestMapping(method = RequestMethod.GET)
     public ModelAndView getComments() {
     ModelAndView modelAndView = new ModelAndView("comments");
     List comments = commentsService.getComments();
     modelAndView.addObject("comments", comments);
     modelAndView.addObject("commentForm", new Comment());
     return modelAndView;
   }

With this code in place, whenever the user’s browser is redirected to /comments, Spring will use the getComments method which then sets off a chain of interactions that have almost a domino effect. CommentsController then uses the method-level @RequestMapping annotation to base its calculations, which then bind with GET requests under the class-level @RequestMapping annotation, and then finally combines with the /comments URI to complete the entire action. All of this is enabled with these rather short and simple lines of code.

We will go over modeling data and rendering views to make the application work better for you later in the piece, but for now we will show you exactly what purpose these two areas serve. Essentially a Spring MVC view is a way of organizing and rendering all the data in the application so then it can be presented to the user. A Spring MVC model is in control of all the data while JSP components are used to render Comment class occurrences as HTML. A ViewResolver is then required in order to take the model that is returned by the controller and decide which view to use and how to bind that model so then it can be presented directly to the user.

@RequestMapping(method = RequestMethod.GET)
   public ModelAndView getComments() {
     ModelAndView modelAndView = new ModelAndView("comments");
     List comments = commentsService.getComments();
     modelAndView.addObject("comments", comments);
     modelAndView.addObject("commentForm", new Comment());
     return modelAndView;
   }

If you’re using the getComments method that is used in the short lines of code above then it should return a model bound by the name “comments”. Using the ViewResolver, Spring MVC then takes the model and looks for the file entitled /WEB-INF/views/.jsp. This allows the model to passed along easily and rendered as a HTML. Because the view name is comments, VewResolver will use the file /WEB-INF/views/comments.jsp to completely render the view. As you will see later on, these actions can be deployed so then they can be used in very specific areas of the web application without disturbing other areas of operation.

Once all this is put in place, all the information is able to flow through Spring MVC, even with a single web request. First the user will direct the browser to http://localhost:8080/spring-mvc-bootstrap/, which will then allow the browser to submit a HTTP GET request. Then the DispatcherServlet that operates inside Spring MVC will intercept the HTTP GET request that has been triggered by the user and look for the handler. Upon finding it a request is made to the IndexController using the getIndex method, and the view name redirect:comments is selected and sent back to Spring MVC. Finally, Spring MVC will send an HTTP 301 (redirect) reply to the browser, thus completing the action that has been designed by the code.

After this happens, this makes the browser submit a second HTTP GET request to http://localhost:8080/spring-mvc-bootstrap/comments, and DispatcherServlet will once again intercept the request and looks for the handler. When it has been found, CommentsController is requested to use the getComments method, and a list of comments are created. This list is then returned with view name comments and Spring MVC resolves the view as /WEB-INF/views/comments.jsp. To conclude, Spring MVC then renders the view and returns it to the user in the form as an HTTP 200 (OK) response, completing the whole process.

Ultimately, the whole process works a lot smoother then it may look when it is described in detail, and it is extremely effective. Spring MVC manages all the complexities that come with mapping requests and controller methods, wiring all the components together and locating and rendering views. This means that making a Java web application is made much more simpler, so then you can adapt and evolve the application in the future if you wish.

JSON and XML

When you are building a web application, it can mean being able to write and build code that is able to speak to many protocols. When it comes to Spring MVC, it has modular architecture that allows you to translate these and other protocols into basic Java classes that are then able to be placed above controller implementations without being noticed. Here we will look at how you support both JSON and XML in the application without getting too confused about the different protocols. This can be particularly useful when you are looking to get the most out of your web application once you have created the basic through Spring MVC, as it will give you more control over what the end result will be.

When it comes to mapping to and from XML, few things are more effective than JAXB. It includes a lot of useful annotations that can be used to decorate Java classes. At the point of the release of version 1.6, there are many JAXB implementations which include the core Java runtime. Even though there are several, only a few are actually needed if you want to build a strong XML and JSON data model.

@XmlRootElement
   @XmlAccessorType(XmlAccessType.FIELD)
   public class Comment {
     @XmlAttribute
     public Long id;
     @XmlElement
     public String authorName;
     @XmlElement
     public String authorEmail;
     @XmlElement
     public String authorUrl;
     @XmlElement
     public String message;
     public Long getId() {
       return id;
     }
     public void setId(Long id) {
       this.id = id;
     }
     public String getAuthorName() {
       return authorName;
     }
     public void setAuthorName(String authorName) {
       this.authorName = authorName;
     }
     // additional methods excluded for brevity

When it comes to the code that is presented above, the @XmlRootElement indicates that a class doesn’t have to simply remain a nested XML element. Instead this annotation allows the XML element to become a top-level part of the application. The @XmlAccessorType annotation allows fields to be accessed directly rather than through accessor methods, which as we see later can often be unnecessary. It achieves this by specifying exactly how fields can be accessed by the JAXB implementation. It goes without saying that this makes processes and any commands a lot smoother and responses are made a lot quicker.

The @XMLAttribute and @XMLElement annotations both operate with the XML element respectively. They both pick out specific pieces of data as properties and nested XML elements. When all this is put together, it will create a map to an XML document similar to the code that you can see below.

<comment id="123">
     <authorName>John Doe</authorName>
     <authorEmail></authorEmail>
     <authorUrl></authorUrl>
     <message>Hello, world!</message>
   </comment>

When it comes to parsing and binding JSON against Java objects, the best and most useful library is Jackson. It has a particularly useful feature that allows it to use JAXB annotations to configure any JSON serializations. This is an optional feature, but still a very useful one when using Spring MVC.  When used it doesn’t require the user to make any changes to the Comment class in order to maintain JSON support within the application. This obviously is another big time saver, which will give you more free time to address other ways of modifying the web application to suit whatever needs you have, or maybe using advanced methods with Java to help expand your application.

If you were to use the exact same JAXB annotations that we used in the previous coding example, you will be able to create a JSON document from a comment. It will also look very similar to the XML version we saw earlier, as you can see below. This means from a user’s perspective it will make the coding being used much easier to read and edit.

{
     "id": 0,
     "authorName": "John Doe",
     "authorEmail": "",
     "authorUrl": "",
     "message": "Hello, world!"
   }

Because the user is using both XML and JSON in the exact same web application, he or she needs to be able to specify exactly which format they want to use. When it comes to the HTML, this is a specification that is supposed to occur in the headers known as Accept and Content-Type HTTP. Spring MVC is able to handle this approach as it is handled with the ContentNavigationViewResolver. This can be configured using the variety of views and view resolvers that are selected at HTTP request time. This is usually based on the user’s Content-Type header, as you can see in the coding below.

@Bean
   public ViewResolver viewResolver() throws JAXBException {
     Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
     jaxb2Marshaller.setClassesToBeBound(Comments.class, Comment.class);
     MarshallingView marshallingView = new MarshallingView(jaxb2Marshaller);
     ContentNegotiatingViewResolver contentNegotiatingViewResolver =
        new ContentNegotiatingViewResolver();
     contentNegotiatingViewResolver.setDefaultViews(Arrays.
        asList(new MappingJacksonJsonView(), marshallingView));
     return contentNegotiatingViewResolver;
   }

In these particular lines of code we can see that two different views have been configured at the same time. One provides the JAXB serialization and the other provides the JSON serialization. These are returned to Spring MVC as a single ViewResolver instance after they are returned by a ContentNegotiatingViewResolver, which has taken on both of the serializations as default views. You are then able to use cURL to run a very simple test on both of these to make sure they are both operating correctly.

For XML:

curl -H "Accept: application/xml" http://localhost:8080/spring-mvc-json-and-xml/comments/

For JSON:

curl -H "Accept: application/json" http://localhost:8080/spring-mvc-json-and-xml/comments/

Rendering Views: View Templates

The named view is mapped and then configured by Spring, that uses ViewResolver to turn it into an actual view. It then merges the view to the model and sends it back to the user as rendered view through HTTP response, almost like a quick response to an email. When a direct view resolution is required, Spring can be rather simply configured with a ViewResolver command that will know automatically where it can find new template files. Here we will go through the View Template pattern in relation to rendering views, and how to use a more traditional Java implementation tool so then you can drive user experience of the web application

Without a doubt, the most common pattern used when it comes to rendering web pages is the View Template pattern. That is because it is one of the more traditional patterns that has been used over the years, and is considered one of the better patterns to use if you’re looking to improve user experience in any way. In the system we are about to take you through you will notice that there are a few placeholders here and there. These are read by vie template technology and helps to create the finished HTML view ready to be viewed by the user.

When using Java web applications, the most trusted view template implement system is JSP. JSP is supported by Spring MVC via the InternalResourceViewResolver. The resolver will then look for files ending with .jsp in the application’s WEB-INF/views/ directory. When Spring checks in this directory for .jsp files, it will use any that are available there regardless of the file name and will compile them for rendering.

If you are looking to display a group of comments while using JSP, it will use the “ form of punctuation along with a ${} pattern when it is necessary to look up field value. This particular action relies on the use of the JavaBean pattern, where named fields are able to access and mutate the various methods. If you are planning on displaying a group of comments in your web application, then a line of code should look something like this:

<c:forEach var="comment" items="${comments}">

More and more people are now deciding to move on from the more traditional view template technology and trying more modern things. Mustache is one of the more well respected of the new implementation systems, and it can work in many languages including Java, so it has the attraction of being useful for other actions. Another big selling point of Mustache is that it can entire HTML and JavaScript frontends with no need to spend time creating any backends. The frontend can be programmed to work as the backend at the same time without having to make any changes to the view templates themselves.

Spring is not able to support Mustache straight away, but with a Mavern dependency it can be added with relative ease.

<dependency>

<groupId>com.github.sps.mustache</groupId>

<artifactId>mustache-spring-view</artifactId>

<version>1.0</version>

</dependency>

Using Mustache is pretty much the same as before, involving the same placeholders and symbols. Now though there is an additional step which is of significant importance. A Spring ResourceLoader has to be placed in a Mustache TemplateLoader. While the ResourceLoader is a part of Spring, it can be easily captured as an argument ready to be moved over using ViewResolver. When a collection of comments are displayed with Mustache, there are a lot of similarities with JSP. The only major difference is that you will no longer need accessor or mutator methods as you can use a direct access to fields.

{{#comments}}
     <div>
       <h2>Comment {{id}}</h2>
       <p>{{message}}</p>
       <p>{{authorName}}</p>
       <p>{{authorEmail}}</p>
       <p><a href="{{authorUrl}}">{{authorUrl}}</a></p>
     </div>
   {{/comments}}

Modeling Data: Separation of Concern

When it comes to mapping the flow of data as it passes through the different layers in an MVC application, it can get rather complicated in relation to the models. On the surface it looks like the obvious solution to this problem is to attempt to simplify the model by choosing a generic representation of the data to essentially copy and paste from layer to layer. This however can cause a lot of problems with the data model and can leave the application rather weak and flat.

The view, persistence layers, and controller are the most common layers in an MVC application. The view layer generally only responds whenever the user decides to enter any information, in particular data that has kept in a form-based manor. The persistence layer depends entirely on remaining data that is put into practice after other functions have been implemented, while the controller layer tends to pull in information depending on its hybrid relational style. Here we will look at making clear separations of concern so then operations run smoothly and the data that is produced is well defined.

The JSP element in Spring MVC works well with JavaBean-style instances that are flat and are employing what are known as “getter/setter” methods. While this is a good way to work and can make dealing with the web applications much quicker and easier, the models are tailored so then they are appropriate and neat enough for the user to read them. In other words, while it may work for the user when checking the data, it can mean that it doesn’t map well as a domain model. For example, the data from the author could be stored in an Author class while the actual messages are being stored in an UnsavedComment class. The could make things a little messy to handle as a domain model, which is why it is best to map all the data within the controller. This will then allow the application to pass the data along to create a more organized structure that will store everything in an object-orientated manor.

// continued from CommentForm above
     public UnsavedComment toComment() {
       Author author = new Author(authorName, authorEmail, authorUrl);
       return new UnsavedComment(author, message);
     }
   }
   public class Author {
     public final String name;
     public final String email;
     public final String url;
     public Author(String _name, String _email, String _url) {
       name = _name;
       email = _email;
       url = _url;
     }
   }

If however the data being entered into the web application is connected to a relational database, then you might have the added inconvenience of having to transform the data again. This has to be done in this instance because the data has to fit the table structure that has been created at the backend. This could be something that you can avoid if the system being used is rather simple, but if complex data models are being used than transforming the data using this method is of the highest importance. Otherwise any attempt you have made to make the data model more organized in the domain could have been all for nothing.

The main reason this is all so important when you are managing a web application is that it keeps everything organized and ensures that the overall design is smoother and more efficient. If data is separated discreetly into different stages then it also makes it easier for you to manage in the future if ever you want to make any other changes. For example, application data should be kept in a application-specific structure, form data held in a form-specific structure, and so on and so forth.

Translating data models across different layers of the application is a time consuming task that can leave your patience rather thin, but the benefits in taking this approach are rather significant. Distinct and logically managed sections of the web application will be able to operate based on the most appropriate model without the inconvenience of being taxed with something that doesn’t fall within its remit. For example, if this method were not being employed then a change to form-based data could have an effect on the other areas of the model, which could lead to more maintenance and more time wasted trying to keep track of all the changes that are being made. Employing this form of organization means that form-based data would not have to operate for anything other than form-based areas of operation.

Page Last Updated: November 2013

Featured course

Spring Professional Certification Exam Tutorial - Module 05

Last Updated January 2020

Highest Rated
  • 3.5 total hours
  • 12 lectures
  • Intermediate Level
4.8 (507)

Spring MVC and the Web Layer | By Dominik Cebula

Explore Course

Spring MVC students also learn

Empower your team. Lead the industry.

Get a subscription to a library of online courses and digital learning tools for your organization with Udemy Business.

Request a demo