Spring MVC Beginner’s Guide
上QQ阅读APP看书,第一时间看更新

Time for action – understanding InternalResourceViewResolver

We instruct Spring to create a bean for an InternalResourceViewResolver class, but why? Who is going to use this bean? What is the role of the InternalResourceViewResolver bean in Spring MVC? Find the answer to these questions through the following exercise:

  1. Open DispatcherServlet-context.xml; you can find this file under the src/main/webapp/WEB-INF/spring/webcontext/ directory in your project.
  2. Change the prefix property value of the InternalResourceViewResolver bean as follows:
    <property name="prefix" value="/WEB-INF/views/" />
  3. Now, run your webstore project again and enter the URL http://localhost:8080/webstore/. You will see an HTTP Status 404 error message in your browser as shown in the following screenshot:
    Time for action – understanding InternalResourceViewResolver

    An error page displaying the no resource found message

  4. Then, rename the jsp directory (/src/main/webapp/WEB-INF/jsp) to views.
  5. Finally, run your application and enter the URL, http://localhost:8080/webstore/. You will see the welcome message again.

What just happened?

After changing the prefix property value of the InternalResourceViewResolver bean, we got an HTTP Status 404 error when we entered the URL, http://localhost:8080/webstore/, in the browser. The HTTP Status 404 error means that the server could not find the web page that we asked for. If that is the case, then which web page did we ask for?

As a matter of fact, we didn't ask for any web page from the server directly; instead, the dispatcher servlet asks a particular web page from the server. What we already learned is that the dispatcher servlet invokes a method in any of the controller beans that can serve this web request. In our case, this method is nothing but the welcome method of our HomeController class, because this is the only request mapping method that can match the request path of the given URL, http://localhost:8080/webstore/, in its @RequestMapping annotation.

Now, observe the following:

  • The prefix property value of the InternalResourceViewResolver bean definition in DispatcherServlet-context.xml; that is, /WEB-INF/views/
  • The return value of the welcome method from the HomeController class; that is, welcome
  • Finally, the suffix property value of the InternalResourceViewResolver bean, that is, .jsp

If you combine these three values together, you will get a web page request URL: /WEB-INF/views/welcome.jsp. Now, note the error message in the previous screenshot, showing the 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 file path by prepending the configured prefix value and appending the suffix value with the view name—the view name is the value usually returned by the controller method. So, the controller method doesn't return the path of the actual view file; it returns only the logical view name. It is the job of InternalResourceViewResolver to form the URL of the actual view file correctly.

Who is going to use this final formed URL? The answer is the dispatcher servlet. After getting the final formed URL of the view file from the view resolver, the dispatcher servlet will try to get the view file from the server. During this time, if the formed URL is found to be wrong, then you will get the HTTP Status 404 error.

Usually, after invoking the controller method, the dispatcher servlet will wait to get the logical view name from it. Once the dispatcher servlet gets the logical view name, it gives this name 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.

However, why did we get the error in step 3? Since we changed the prefix property of the InternalResourceViewResolver bean in step 2, the URL path value returned from InternalResourceViewResolver became /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 4 to align it with the path generated by InternalResourceViewResolver so that everything works fine again.