Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Understanding View Resolution, Forwarding, Redirection, and Static Resource Handling in Spring MVC

Tech May 10 4

Core Mechanism of View Resolution in Spring MVC

Spring MVC supports customizable view components. The framework allows developers to configure different view technologies through XML configuration. For instance, when using Thymeleaf as the template engine, the following setup is typically defined in springmvc.xml:

<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
    <property name="characterEncoding" value="UTF-8" />
    <property name="order" value="1" />
    <property name="templateEngine">
        <bean class="org.thymeleaf.spring6.SpringTemplateEngine">
            <property name="templateResolver">
                <bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
                    <property name="prefix" value="/WEB-INF/templates/" />
                    <property name="suffix" value=".html" />
                    <property name="templateMode" value="HTML" />
                    <property name="characterEncoding" value="UTF-8" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

This configuration tells Spring MVC that Thymeleaf should be used for rendering views. Switching to another view technology only requires modifying this configuration—no code changes are needed. This design adheres to the Open-Closed Principle (OCP), enabling easy extension without modifying existing code.

Supported View Types in Spring MVC

Spring MVC natively supports multiple view types:

  • InternalResourceView: Built-in support for JSP templates.
  • RedirectView: Used for HTTP redirection.
  • ThymeleafView: Third-party integration for Thymeleaf templates.
  • FreeMarkerView: For FreeMarker-based templates.
  • VelocityView: For Velocity templates.
  • PDFView, ExcelView: Specialized views for generating PDFs and Excel files.

These can be easily swapped by adjusting the view resolver configuration.

Key Interfaces in View Handling

  • DispatcherServlet: The central front controller responsible for request dispatching.

    • Main method: doDispatch()
  • ViewResolver Interface: Translates logical view names into physical view paths.

    • Method: View resolveViewName(String viewName, Locale locale)
  • View Interface: Renders model data into a final output (e.g., HTML).

    • Method: void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
  • ViewResolverRegistry: Registers view resolvers during application startup. If multiple resolvers exist, they are ordered by their order property.

To implement a custom view component:

  1. Create a class implementing ViewResolver, and override resolveViewName() to map logical names to physical resources.
  2. Create a class implementing View, and override render() to transform template content into HTML output.

When using Thymeleaf, the actual classes involved are ThymeleafViewResolver and ThymeleafView. With JSP, it's InternalResourceViewResolver and InternalResourceView.

Flow of View Resolution

Scenario: Using Thymeleaf

  1. Client sends an HTTP request.
  2. DispatcherServlet receives the request.
  3. Request is mapped to a controller method.
  4. Controller returns a logical view name (e.g., index).
  5. DispatcherServlet invokes ThymeleafViewResolver.resolveViewName() to convert index/WEB-INF/templates/index.html.
  6. A ThymeleafView instance is created and returned.
  7. ThymeleafView.render() processes the template, converts it to HTML, and sends it back to the client.

Scenario: Using JSP

  1. Same initial steps.
  2. InternalResourceViewResolver resolves index/WEB-INF/jsp/index.jsp.
  3. InternalResourceView.render() forwards the request internally and renders the JSP.

Logical to Physical View Mapping

The mapping depends on the configured view resolver. For example:

  • With Thymeleaf config:

    • Logical: index
    • Physical: /WEB-INF/templates/index.html
  • With JSP config:

    • Logical: index
    • Physical: /WEB-INF/jsp/index.jsp

Debugging View Creation

By setting breakpoints in DispatcherServlet.doDispatch() and tracing through render() methods, you can observe which view objects are instantiated:

  • When returning "index", the system uses ThymeleafView.
  • When using "forward:/b", the system creates InternalResourceView.
  • When using "redirect:/b", the system creates RedirectView.

Note: forward: and redirect: are not logical view names—they are direct instructions to the dispatcher. Thus, no view resolver is invoked for these cases.

Forwarding vs. Redirection in Spring MVC

Forwarding

  • One HTTP request.
  • Browser URL remains unchanged.
  • Server-side internal jump.
  • Can access protected resources like those under /WEB-INF.
  • Syntax: return "forward:/target-path";

Example:

@RequestMapping("/a")
public String toA() {
    return "forward:/b";
}

This triggers a server-side forward to /b, creating an InternalResourceView.

Redirection

  • Two HTTP requests.
  • Browser URL updates.
  • Client-side redirect initiated by the server.
  • Can cross domains or applications.
  • Cannot access /WEB-INF directly via browser.
  • Syntax: return "redirect:/target-path";

Example:

@RequestMapping("/a")
public String toA() {
    return "redirect:/b";
}

This results in a 302 response, prompting the client to make a new request to /b, where RedirectView is created.

Cross-application redirect:

return "redirect:http://localhost:8080/springmvc2/b";

Configuring View Controllers

The <mvc:view-controller> element maps a URL directly to a view without requiring a controller.

<mvc:view-controller path="/" view-name="index" />

This enables direct access to the index view at the root path. However, this feature requires <mvc:annotation-driven /> to be present in the configuration—otherwise, controllers won't be recognized, leading to 404 errors.

Serving Static Resources

Due to DispatcherServlet's url-pattern being set to /, all requests—including static assets—are routed through it, causing 404s unless handled properly.

Solution 1: Enable Default Servlet

Enable Tomcat’s built-in DefaultServlet to handle static files:

<mvc:annotation-driven />
<mvc:default-servlet-handler />

Tomcat already includes the DefaultServlet in its default web.xml. This setup ensures that if DispatcherServlet cannot find a handler, the request falls back to the default servlet, which serves static content from the web application root.

Solution 2: Use mvc:resources

Define explicit mappings for static resources:

<mvc:annotation-driven />
<mvc:resources mapping="/static/**" location="/static/" />

This rule means any request starting with /static/ will be served from the /static/ directory within the web application. This approach requires <mvc:annotation-driven /> to be active.

Both solutions work, but mvc:resources gives more control over what gets served and how.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.