In the last chapter, you saw how to use some of the Spring tags that could only be used in JSP and JSTL Views, but Spring has excellent support for other View technologies as well. Spring MVC maintains a high level of decoupling between the View and the Controller; the Controller knows nothing about the View except the View name. It is the responsibility of the view resolver to map the correct View for the given View name.
In this chapter, we will have a deeper look into Views and view resolvers. After finishing this chapter, you will have a clear idea about:
As I already mentioned, Spring MVC does not make any assumptions about specific View technologies. According to Spring MVC, a View is identifiable as an implementation of the org.springframework.web.servlet.View
interface:
public interface View { String getContentType(); void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception; }
The render method from the Spring MVC View interface defines, as the main responsibility for a view
object, that it should render proper content as a response (javax.servlet.http.HttpServletResponse
) based on the given Model and request (javax.servlet.http.HttpServletRequest
).
Because of the simplicity of the Spring MVC View interface, if we want we can write our own View implementation. But Spring MVC provides many convenient View implementations that are ready to use by simply configuring them in our web application context configuration file.
One such View is InternalResourceView
(org.springframework.web.servlet.view.InternalResourceView
) for rendering a response as a JSP page. Similarly, there are other View implementations such as RedirectView
, TilesView
, FreeMarkerView
, VelocityView
, and more available for specific View technologies. Spring MVC does not encourage you to couple the view
object with the Controller as it will lead the controller method to tightly couple with one specific View technology. But if you want to do so, you can do something like the following code snippet:
@RequestMapping("/home") public ModelAndView greeting(Map<String, Object> model) { model.put("greeting", "Welcome to Web Store!"); model.put("tagline", "The one and only amazing web store"); View view = new InternalResourceView("/WEB-INF/views/welcome.jsp"); return new ModelAndView(view, model); }
In this code handler method, we didn't return any logical View name; rather we instantiated InternalResourceView
out of welcome.jsp
directly and composed it into the ModelAndView
(org.springframework.web.servlet.ModelAndView
) object. This example is not encouraged since it tightly coupled the greeting
handler method with InternalResourceView
. Instead, what we can do is return a logical View name and configure an appropriate view resolver of our choice in our web app context to create a view
object.
Spring comes with quite a few view resolvers to resolve various type of Views. You already saw how to configure InternalResourceViewResolver
as our view resolver to resolve JSP Views in
Chapter 2, Spring MVC Architecture – Architecting Your Web Store, and you also saw how InternalResourceViewResolver
resolves a particular logical View name into a View. Anyhow, I will repeat it briefly here.
InternalResourceViewResolver
will resolve the actual View file path by prepending the configured prefix
value and appending the suffix
value with the logical View name; the logical View name is the value usually returned by the Controller's method. So the Controller's method didn't return any actual View, it just returns the View name. It is the role of InternalResourceViewResolver
to form the correct URL path for the actual InternalResourceView
.