How to properly use multiple controllers in Spring MVC

13,856

You almost got it right. The prefix has to be absolute here to make it work the way you want it to. That is: The prefix for the view-resolver has to be set as an absolute:

resolver.setPrefix("WEB-INF/views/");

And, when you return the view names from the @RequestMapping methods, they have to be the paths relative to your view-resolver's prefix path. So, in the homeController, you should return home/index, and in your dataController, you should return data/index.

Share:
13,856
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I am trying to use 2 controllers with one dispatcher servlet in Spring MVC. But I am running into 404 errors when trying to render the views. The dispatcher is pretty straightforward, from web.xml:

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    and with the following configuration:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        ...
    <context:component-scan base-package="com.mycompany.azalea" />
    
    <mvc:annotation-driven />
    
    </beans>
    

    The controllers are:

    package com.mycompany.azalea;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping(value = "/home")
    public class homeController {
    
        @RequestMapping(value = "/")
        public String home() {
             return "index";
        }
    }
    

    and

    package com.mycompany.azalea;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping(value = "/data")
    public class dataController {
    
        @RequestMapping(value = "/")
        public String home() {
             return "index";
        }
    }
    

    and I am using a pretty standard resolver:

    @Configuration
    public class AppConfig {
    
    // Resolve logical view names to .jsp resources in the /WEB-INF/views directory
    @Bean
    ViewResolver viewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("WEB-INF/views/");
            resolver.setSuffix(".jsp");
            return resolver;
        }
    }
    

    Views are set up under WEB-INF/views/home/ and WEB-INF/views/data/

    However if I try to request a URL like http://localhost:8080/Azalea/home/

    I get an entry in the GlassFish log:

    SEVERE: PWC6117: File ".../build/web/home/WEB-INF/views/index.jsp" not found

    instead of the expected request for

    ".../build/web/WEB-INF/views/home/index.jsp"

    Same pattern for "/data". It essentially looks like the request mapping is inserted into the wrong position in the request.

    My current work around is to modify the resolver to

    resolver.setPrefix("../WEB-INF/views/"); 
    

    and return the following from the controller:

    public class homeController {

        @RequestMapping(value = "/")
        public String home() {
             return "home/index";
        }
    }
    

    But this seems to be a suboptimal solution. Please let me know if you have any suggestions.