==================================================================================================
今天试了下spring mvc遇到个很奇怪的事情,按照书上配置访问时总是出现如下警告:
org.springframework.web.servlet.DispatcherServlet noHandlerFound
警告: No mapping found for HTTP request with URI [/myspring/WEB-INF/jsp/hello.jsp] in DispatcherServlet with name 'spring'
web.xml
Xml代码
- <servlet>
- <servlet-name>spring</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/springContext.xml</param-value>
- </init-param>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>spring</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
<servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springContext.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
springContext.xml
Xml代码
- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/jsp/" />
- <property name="suffix" value=".jsp" />
- </bean>
-
- <bean name="/hc" class="com.hj.controllers.HelloController"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <bean name="/hc" class="com.hj.controllers.HelloController"/>
HelloController.java
Java代码
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request,
- HttpServletResponse response) throws Exception {
-
- return new ModelAndView("hello");
- }
@Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("hello"); }
在项目/WEB-INF/jsp目录下防止hello.jsp文件。按照上述配置访问http://localhost:8081/myspring /hc,应该是出现hello.jsp内容才对,但是却出现了一开始提到的警告。我搜索了许多地方,结果在一老外的提供中找到了同样的问题(http: //forum.springsource.org/archive/index.php/t-71263.html),解决方法老外也说明了,只是不知 道为什么。
就是将web.xml中
Xml代码
- <servlet-mapping>
- <servlet-name>spring</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
<servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
改成
Java代码
- <servlet-mapping>
- <servlet-name>spring</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
<servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
然后按照上述地址就可以访问,但是这是为什么呢?有谁知道请留言,不胜感谢!
问题补充
我 的意思就是为什么/*无法匹配,而/却可以匹配到
原文:http://www.javaeye.com/problems/36433
————————————————————————————————————————————
上述问题我也遇到,所以就记录下来。
总是现象就是:
spring用到forward("/WEB-INF/jsp/*.jsp")
而forward当然是又要经过web.xml的映射的,
然后,在URL匹配时,
<url-pattern>/</url-pattern> 不会匹配到*.jsp,不会进入spring的DispatcherServlet类
<url-pattern>/*</url-pattern> 会匹配*.jsp,导致进入spring的DispatcherServlet类,然后去寻找controller,接着找不到对应的controller所以报错。
试验了一下,改为 <url-pattern>/</url-pattern> 果然就不会报错了,唉,还以为不能解决,为此还换成了velocity作为视图,算了,继续用velocity吧,简单点。
总之,关于web.xml的url映射的小知识:
<url-pattern>/</url-pattern> 会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url
<url-pattern>/*</url-pattern> 会匹配所有url:路径型的和后缀型的url(包括/login,*.jsp,*.js和*.html等)
============================================================================================
译自《Servlet Specification Version 2.4》,转载请注明出处!
把请求映射到Servlet
在这个章节中描述的映射技术都需要web容器把客户端的请求映射到Servlet。
SRV.11.1 使用URL路径
当收到一个客户端请求时,web容器决定将请求转交给那个web应用处理。被选择的web应用必须是从前向后匹配的请求URL的最长的上下文路径,匹配的URL部分就是映射到Servlet时的上下文路径。
Web容器下一步必须使用下面描述的路径映射规则找到处理请求的Servlet。
用于映射到Servlet的路径是请求的URL去掉上下文路径和路径参数(如http://localhost/myapp/a /a.jsp?msg=hello,上下文路径为/myapp,路径参数为?msg=hello)。按序使用以下URL路径映射规则,第一次匹配成功的规 则将被使用,并且将不会尝试继续匹配:
1. 容器将试图为请求的路径查找一个精确匹配的Servlet路径。匹配成功则选择该Servlet。
2. 容器将递归的匹配最长路径前缀,这是通过使用字符'/'做路径分隔符从后往前分隔路径树,一次一个目录,最长的匹配决定了该Servlet被选择。
3. 如果URL路径最后的部分包含一个扩展名(如.jsp),Servlet容器将尝试匹配一个处理该后缀请求的Servlet,扩展名定义为最后一个'/'后面的部分中字符'.'后的部分。
4. 如果前面的三个规则都不能匹配到一个Servlet,容器将尝试为请求的资源使用内容服务,如果应用定义了默认的Servlet,则它将被使用。
容器的匹配过程必须使用大小写敏感的字符串比较。
SRV.11.2 映射详述
在Web应用部署描述符中,下面的语法被用于定义映射:
• 以'/'开头且以‘/*’结束的字符串用于路径映射。
• 以'*.'开头的字串串用于扩展名映射。
• 仅包含'/'的字符串表明对应的Servlet为应用默认的Servlet。在这种情况下Servlet路径是请求的URI去掉上下文路径并且路径信息为null。
• 所有其它的字符串都被只能用于精确匹配。
SRV.11.2.1 隐式映射
如果容器包含一个内部的JSP容器,则*.jsp扩展名将映射到该容器。允许JSP页面一经请求就执行。这种映射称为隐式映射。如果*.jsp映射被定义成web应用,其优先级高于隐式映射。
一个Servlet容器允许做更多的隐式映射当明确的映射具有高优先级时。例如,*.shtml的隐式映射可以被用于映射成在服务器上包含具体的功能。
SRV.11.2.2 映射例子
思考下面的映射:
Table SRV.11-1 Example Set of Maps
Path Pattern Servlet
/foo/bar/* servlet1
/baz/* servlet2
/catalog servlet3
*.bop servlet4
紧接着是映射到结果:
Table SRV.11-2 Incoming Paths Applied to Example Maps
Incoming Path Servlet Handling Request
/foo/bar/index.html servlet1
/foo/bar/index.bop servlet1
/baz servlet2
/baz/index.html servlet2
/catalog servlet3
/catalog/index.html “default” servlet
/catalog/racecar.bop servlet4
/index.bop servlet4
注意例子中的/catalog/index.html和/catalog/racecar.bop并没有映射到/catalog,因为/catalog是一个精确映射。