user1795832
user1795832

Reputation: 2160

Spring MVC page to page navigation not working

I have two pages: home.jsp, and stylechoosertable.jsp. home.jsp has a simple link going to stylechoosertable.jsp. Both are in src - main - webapp - views. Starting the app runs fine, loading home.jsp is fine. However, when I click the link, it goes to a 404 Not Found page.

Here is HomeController.java

@Controller
public class HomeController {

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Model model) {
        logger.info("Welcome home! The client locale is {}.");      
        return "home";
    }
}

Here is CSSTableController.java

@Controller
public class CSSTableController {

    private static final Logger logger = LoggerFactory.getLogger(CSSTableController.class);
    private final CSSService cssService;

    @Autowired
    public CSSTableController(CSSService cssService) {
        this.cssService = cssService;
    }

    @RequestMapping(value = "/stylechoosertable.jsp", method = RequestMethod.GET)
    public List<StyleChooser> get() {
        return cssService.getAllStyleChoosers();
    }

}

servlet-context.xml

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

web.xml

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

A couple of things I've noticed:

  1. Only local:8080/myspringmvc/ brings up the home page. local:8080/myspringmvc/home.jsp brings up the same 404 error, which I don't get.

  2. On start, I can see it doing the Request/Handler mappings properly:

INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/stylechoosertable.jsp],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.util.List com.css.genapp.CSSTableController.get()

INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.css.genapp.HomeController.home(org.springframework.ui.Model)

  1. It doesn't throw any org.springframework.web.servlet.PageNotFound errors when I go to home.jsp or stylechoosertable.jsp, so I know the mapping is there.

I can't figure out why it doesn't "hit" my stylechoosertable.jsp. Any ideas?

Upvotes: 2

Views: 5848

Answers (2)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279940

Most Servlet containers register a Servlet implementation to handle JSPs. They would look like

<servlet>
    <servlet-name>jspServlet</servlet-name>
    <servlet-class>com.example.JspServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>jspServlet</servlet-name>
    <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

The *.jsp is known as an extension mapping. A Servlet container knows about this Servlet and the ones you've registered. The container doesn't know anything about your @Controller beans. That are relevant to Spring only.

When a Servlet container receives a request, it goes through an order specified in the Servlet specification for matching a particular Servlet based on its mapping(s). Basically, it first checks for an exact match, then it tries to do path matching (patterns like /something/*), then it does extension mapping, and finally, if no matches were found, uses the default servlet, a servlet mapped to /. In this case, your DispatcherServlet (which runs the Spring MVC stack) is mapped to /, so it is the default servlet.

When you send your request to

local:8080/myspringmvc/home.jsp

the path satisfies the extension mapping of *.jsp and therefore the container uses the JspServlet to handle the request. This JspServlet tries to find an appropriate resource, but doesn't. Remember that JSPs inside WEB-INF are not accessible publicly/externally. It therefore returns a 404.

When you send your request to

local:8080/myspringmvc/ 

the default servlet is chosen because nothing else can match that path. The DispatcherServlet looks up its handlers and finds

@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Model model) {
    logger.info("Welcome home! The client locale is {}.");      
    return "home";
}

By returning the view name home and because you've registered the appropriate InternalResourceViewResolver, Spring will do a RequestDispatcher#forward(..) to that JSP. That request will again be matched by the Servlet container, but this time, to the JspServlet. Because this is an internal call (and the path is right), the request will be completed.

Similarly, for /stylechoosertable.jsp, the JspServlet is chosen before your DispatcherServlet could do anything about it.

It doesn't throw any org.springframework.web.servlet.PageNotFound errors when I go to home.jsp or stylechoosertable.jsp, so I know the mapping is there.

The DispatcherServlet is never involved, so it doesn't have the chance to log anything.

Upvotes: 2

abhi
abhi

Reputation: 4792

Well I don't think I am able to get your question properly, still if you want to have simple navigation function from home.jsp, i.e on click of the link, it should go to stylechoosertable.jsp, then a definite solution would be just have a link like

<a href="stylechoosertable">SomeName</a>

Now simply map this in controller

@RequestMapping(value = "/stylechoosertable")
public String goToSCT() {
    return "stylechoosertable";
}

And if there is any stylechoosertable.jsp available in /WEB-INF/views/, it will simply get called.

Second Question the reason behind local:8080/myspringmvc/ working, not local:8080/myspringmvc/home.jsp is basically lack of RequestMapping for /home.jsp, where as for the root URL i.e /, a mapping is there in HomeController

Upvotes: 2

Related Questions