¿Por qué el nombre de bean de /home.jsp no funciona para BeanNameUrlHandlerMapping?

In the following program, if I replace "/home.htm" with "/home.jsp" in dispatcher-servlet.xml and index.jsp, then the server is not able to find home.jsp. Are strings ending with ".jsp" invalid as bean name?

despachador-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <bean name="/home.htm" class="com.sample.HomePageController" />

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

</beans>

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Dynamic Tiles</title>
  </head>
  <body>
    <form action="/home.htm" method="post">
        Please enter your name:&nbsp;
        <input type="text" name="visitorName" />
        <input type="submit" value="Go"/>
    </form>
  </body>
</html>

HomePageController.java

package com.sample;

import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class HomePageController  extends AbstractController {

    private static Logger logger = Logger.getLogger(HomePageController.class);

    HomePageController () {
        logger.info("Constructing HomePageController object");
    };

    public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("Handling request for home.jsp");

        return new ModelAndView("home", "visitorName", request.getParameter("visitorName"));
    }

}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

</web-app>

preguntado el 25 de agosto de 12 a las 10:08

Surprisingly if I change the line <url-pattern>*.htm</url-pattern> in web.xml to <url-pattern>*.jsp</url-pattern>, localhost: 8080 y localhost: 8080 / index.jsp are returning "HTTP Status 404 -". -

2 Respuestas

There are several pieces of your application that need to be modified for it to work as intended. The first piece is the Dispatcher Servlet mapping in web.xml. In Spring the dispatcher is used to route particular requests from the client to Spring controllers within the application. What requests are routed via the dispatcher is determined by the url-pattern specified in the web.xml file for the servlet: org.springframework.web.servlet.DispatcherServlet.

In your case we want to set the url-pattern to something that does not conflict with accessing your jsp files. Since you have specified a viewResolver in your Spring configuration that prefixes generic names with /WEB-INF/jsp/ and suffixes them with .jsp, we must use a url-pattern other than .jsp.

If the .jsp url-pattern were used, a request would first be processed by the dispatcher servlet and routed to any mapped controller. If the controller attempts to use a view name to navigate to another page, for example, home, the view name is prefixed/suffixed resulting in a url: /WEB-INF/jsp/home.jsp. This constructed URL matches the .jsp url-pattern specified for the dispatcher and an attempt to route /WEB-INF/jsp/home.jsp is made, most likely failing because no mapping is found.

To remedy this problem we setup your web.xml as follows:

Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

As you can see, we map the dispatcher to the url-pattern *.do. This allows the dispatcher to be used to route requests without interference with common file prefixes. Changing the url-pattern to *.do requires us to change the action on your form. I modified your form to the following:

Índice.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<html>
<head>
<title>Dynamic Tiles</title>
</head>
<body>
    <form action="home.do" method="post">
        Please enter your name:&nbsp; <input type="text" name="visitorName" />
        <input type="submit" value="Go" />
    </form>
</body>
</html>

I also assumed that all of your .jsp files are located within the WEB-INF directory. This requires us to use a controller to access each of these .jsp files. Mappings to the controllers must be created in your Spring configuration file for the dispatcher and the appropriate controller for index.jsp must be created. Notice that I am using the .do suffix for the mappings.

despachador-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="handlerMapping"
        class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <bean name="/home.do" class="com.sample.HomePageController" />
    <bean name="/index.do" class="com.sample.IndexPageController" />

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

IndexPageController.java

package com.sample;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class IndexPageController extends AbstractController {

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
            HttpServletResponse arg1) throws Exception {
        return new ModelAndView("index");
    }
}

Just to be thorough, I created a home.jsp file to test the application since one was not provided. Here is my home.jsp file:

Inicio.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
    <title>Home</title>
</head>
<body>
<h1>
    Hello, ${visitorName}  
</h1>

<P>  The time on the server is ${serverTime}. </P>
</body>
</html>

Respondido 29 ago 12, 12:08

I am not able to understand why the line in the bracket is not kicking in (<bean name="/home.jsp" class="com.sample.HomePageController" />). BTW, I tried your changes and it is not working. - Ken Russell

Did u register the dispatcher in web.XML? - Kevin Bowersox

Yes, I have given web.xml above. Moreover "/home.htm" is working for the same configuration. - Ken Russell

You decided that dispatcher would only handle .htm-ended urls but then you want it to handle .jsp-ended url. For the latter to work just change url-pattern element's content in web.xml to, for example, something like this:

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

Respondido 26 ago 12, 08:08

If you make this change, you will see that the application will still not be able to find the controller. That is the whole problem. - Ken Russell

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.