
View resolvers
A view resolver helps the Dispatcher servlet to identify the views that have to be rendered as a response to a specific web request. Spring MVC provides various view resolver implementations to identify views and InternalResourceViewResolver
is one such implementation:
@Bean public InternalResourceViewResolver getInternalResourceViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setViewClass(JstlView.class); resolver.setPrefix("/WEB-INF/jsp/"); resolver.setSuffix(".jsp"); return resolver; }
Through the above bean definition is in the web application context configuration (WebApplicationContextConfig
), we are instructing Spring MVC to create a bean for the class InternalResourceViewResolver
(org.springframework.web.servlet.view.InternalResourceViewResolver
). We will see more about the view resolver in Chapter 5, Working with View Resolver.
Time for action - understanding web application context
Okay we have seen enough introductions about web application context now, let's tweak the InternalResourceViewResolver
bean from the web application context configuration (WebApplicationContextConfig.java
) a little bit and observe the effect.
- Open
WebApplicationContextConfig.java
and set the prefix as/WEB-INF/views/
for theInternalResourceViewResolver
bean. Basically yourInternalResourceViewResolver
bean definition should look as follows after your change:@Bean public InternalResourceViewResolver getInternalResourceViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setViewClass(JstlView.class); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; }
- Run your application, then go to the address bar of the browser and enter the following URL:
http://localhost:8080/webstore/welcome
. You will see the HTTP Status 404 error page in the browser:The logical parts of a typical Spring MVC application URL
- To fix this error, rename the folder
/webstore/src/main/webapp/WEB-INF/jsp
to/webstore/src/main/webapp/WEB-INF/views
. - Now run your application and enter the URL
http://localhost:8080/webstore/welcome
; you will see the welcome message again.
What just happened?
After changing the prefix
property value of the InternalResourceViewResolver
bean, when we entered the URL http://localhost:8080/webstore/
welcome
in the browser, we got a HTTP status 404 error. The HTTP status 404 error means that the server could not find the web page that you asked for. Okay if that is the case, which web page did we ask for?
As a matter of fact, we didn't ask for any web page to the server directly; instead the Dispatcher servlet asked for a particular web page to the server. And what we already learned is that the Dispatcher servlet will invoke a method in any of our controller beans that can serve this web request. In our case, that method is nothing but the welcome
method of our HomeController
class, because that is the only request mapping method that can match the request path of given URL http://localhost:8080/webstore/welcome
in its @RequestMapping
annotation.
Now I want you to observe three things:
- The
prefix
property value of theInternalResourceViewResolver
bean definition inWebApplicationContextConfig.java
:/WEB-INF/views/
- The return value of the
welcome
method from theHomeController
class:welcome
- Finally, the
suffix
property value of theInternalResourceViewResolver
bean:.jsp
If you combine these three values together, you will get a web page request URL as /WEB-INF/views/welcome.jsp
. Now notice the error message in the figure after step 2, which is showing a HTTP status 404 error for the same web page URL /WEB-INF/views/welcome.jsp
under the application name /webstore/
.
So the conclusion is that InternalResourceViewResolver
resolves the actual view's file path by prepending the configured prefix
and appending the suffix
value with the view name. The view name is the value usually returned by controller's method. So the controller's method doesn't return the path of the actual view file-it just returns the logical view name. It is the job of InternalResourceViewResolver
to form the URL of the actual view file correctly.
Okay fine, but who is going to use this final formed URL? The answer is the Dispatcher servlet. Yes, after getting the final formed URL of a view file from the view resolver, the Dispatcher servlet will try to get the view file from the server. During that time, if the formed URL is found to be wrong, then you will get a HTTP status 404 error.
Usually after invoking the controller's method, the Dispatcher servlet will wait to get the logical view name from the controller's method. Once the Dispatcher servlet gets the logical view name, it will give that to the view resolver (InternalResourceViewResolver
) to get the URL path of the actual view file. Once the view resolver returns the URL path to the Dispatcher servlet, the rendered view file is served to the client browser as a web page by the Dispatcher servlet.
Okay fine, but why did we get the error in step 2? Since we changed the prefix
property of InternalResourceViewResolver
in step 2, the URL path value returned from InternalResourceViewResolver
would become /WEB-INF/views/welcome.jsp
in step 3, which is an invalid path value (there is no directory called views
under WEB-INF
). That's why we renamed the directory jsp
to views
in step 3 to align it with the path generated by InternalResourceViewResolver
, so everything works fine again.