今天下午下班之前看了看凯歌给的Spring Training的教程的lab篇,我之前有跟着做没有遇到什么问题,但是到了跟Spring MVC integrating的时候,遇到一点点有趣的事情。 这个例子很简单,我照着网上的demo做,然后遇到了点问题,请看下面:项目层次 很简单  
   
然后是web.xml的配置

  1. <servlet>
  2. <servlet-name>SpringMvcDemo</servlet-name>
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  4. <init-param>
  5. <param-name>contextConfigLocation</param-name>
  6. <param-value>
  7. /WEB-INF/servlet-config.xml
  8. </param-value>
  9. </init-param>
  10. <load-on-startup>1</load-on-startup>
  11. </servlet>
  12. <servlet-mapping>
  13. <servlet-name>SpringMvcDemo</servlet-name>
  14. <url-pattern>/*</url-pattern>
  15. </servlet-mapping>

你可以看到这很简单,定义了上下文以及FrontController拦截的请求地址,不过需要注意的我这里的是匹配所有URL请求,包括**.jsp和什么静态的**.png等等--这一点非常重要。 
   然后是servlet-config.xml 那就跟简单了,主要是一个包扫描,因为我这里的controller都是使用annotation,然后是一个render jsp的view resolver。

  1. <context:component-scan base-package="ht.clark.web" />
  2. <!-- View Resolver  -->
  3. <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  4. <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
  5. <property name="prefix" value="/WEB-INF/jsp/"/>
  6. <property name="suffix" value=".jsp"></property>
  7. </bean>

最后便是位于ht.clark.web包下的HomeController:

  1. @Controller
  2. public class HomeController {
  3. @RequestMapping(value="/hi.html",method=RequestMethod.GET)
  4. public ModelAndView Greeting(){
  5. ModelAndView model = new ModelAndView("greeting");
  6. model.addObject("msg" , "Hello to Andy Clark");
  7. return model;
  8. }
  9. }

需要注意的是@RequestMapping配置触发这Greeting方法的来源url,也就是浏览器输入http://localhost:8080/SpringMvcDemo/hi.html将会由dispatcher分配到这方法来处理请求。 
那显示结果的JSP页面也很简单--注意使用了Jstl来解析

  1. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  2. <html>
  3. <body>
  4. <h1>This is my message: ${msg}</h1>
  5. </body>
  6. </html>

准备工作完毕,这里的流程那应该是非常之简单的,首先所有在浏览器中输入的url都会传递到DispatchServlet这里简单的servlet中(因为我们使用的是/*--匹配所有url输入),然后DispatchServlet扫描并过滤出所有标记为@Controller的类以及其中的@RequestMapping的方法,并且找到匹配value="/hi.html"的,也就是Greeting方法并做一些处理,返回一个ModelAndView对象,然后根据DispatchServlet会在Render这个对象时delegate到你在Servlet-config中配置的ViewResolver的具体实现,比如我们这里的InternalResourceViewResolver,它可以render jsp的显示技术。最后会将view name(也就是greeting)找到位于WEB-INF/jsp下的greeting.jsp并显示出来。 
     So,quite straightforward, let's rock and roll! 
Oooops,遇到了一点问题,那就是 
[color=red]

  1. 2010-8-17 0:55:30 org.springframework.web.servlet.DispatcherServlet noHandlerFound
  2. No mapping for [/SpringMvcDemo/WEB-INF/jsp/greeting.jsp] in DispatcherServlet with name 'SpringMvcDemo'

[/color] 
  Why???!!!!  我的第一反应是,首先我的这个greeting.jsp肯定是在jsp下的,no mapping 是请求没找到,然后去上网搜这个错误嘛,肯定也有人遇到,于是来到了最熟悉的StackOverflow,一搜果然有人遇到这种问题,第一链接 No mapping found for HTTP request with URI [/WEB-INF/pages/apiForm.jsp]http://stackoverflow.com/questions/1266303 里面提供的解决方案是将

  1. <servlet-mapping>
  2. <servlet-name>SpringMvcDemo</servlet-name>
  3. <url-pattern>/*</url-pattern>
  4. </servlet-mapping>

改为

  1. <servlet-mapping>
  2. <servlet-name>SpringMvcDemo</servlet-name>
  3. <url-pattern>*.html</url-pattern>
  4. </servlet-mapping>

--也就是将match everything该为match仅以html结尾的url请求。 
  And it works !! 
为什么了? 我看后面的回答:

引用
When you set the url-pattern to /* then all requests will be sent to that DispatcherServlet, which includes the request for JSP rendering. Though it's not true, it's sometimes useful to think of the InternalResourceView (and derived like JstlView) as another HTTP request, since that way you'll see why a request for the JSP is getting picked up by the DispatcherServlet. – ptomli Aug 12 '09 at 15:16 
when i set to / , i the request is render fine. only when i set /* . what is the different / and /* ? – cometta Aug 12 '09 at 15:27 
2     
<url-pattern>/</url-pattern> only matches the URL host/servlet <url-pattern>/*</url-pattern> matches everything under host/servlet, such as /index.html, /foo.jpg and, most importantly in this case, /WEB-INF/pages/apiForm.jsp the * is the wildcard, which says "anything" In the earlier suggestion, *.do matches anything that ends in .do, for example, /foo.do, /foo/bar.do. It doesn't match anything ending in jsp, so a request for /WEB-INF/pages/apiFrom.jsp is not matched, and is not routed to the DispatcherServlet – ptomli Aug 12 '09 at 15:42

我看ptomli回答的很靠谱。 我查了一下为什么会这样了,下班前凯歌让我去看看源码,我看了下当然是主要的扫了几眼,(因为很多东西搞不清楚),结合Api文档,还好大概的流程有了个概念。 
   简要地说,当DispatchServlet接受到需要Render的时候,它会去根据需要Render的技术,比如jsp还是xml还是pdf还是velocity等等,在通过你配置的ViewResolver来选择合适的进行处理,所以这里时候它会将请求委托处理resolution InternalResourceViewResoler以及它的子类JstlViewResolver来处理jsp显示的ViewResolver,其实JstlViewResolver或者是InternalResourceViewResoler而言,它们也只是简单调用了RequestDispatch的forward或者include方法来render jsp页面,但是这forward请求,也就是[/SpringMvcDemo/WEB-INF/jsp/greeting.jsp],正如前面所言它匹配DispatchServlet的url表达式(/*),所以它还会交给DispatchServlet来处理,这个时候它肯定是根据你在配置文件中配置或者Controller中annotation比如requestmapping,如果这个时候Controller有一个方法的RequestMapping(value="/WEB-INF/jsp/greeting.jsp')那就会交给它来处理请求,所以,当我们改为使用*.html时候,[/SpringMvcDemo/WEB-INF/jsp/greeting.jsp]并不匹配*.html的格式,所以它不会进入DispatchServlet,而这正是我们想要的,它也不应该route到DispatchServlet中。 
   所以,这个整个解决问题的过程,还是杰哥说的对,尽管没有说完完整整的自己解决,但是看到别人的解决方案,再想想为什么,然后自己去琢磨,不自觉地有加深对整个框架的理解。

http://clarkht.iteye.com/blog/738820

Spring MVC 遇到的一点点问题(转)的更多相关文章

  1. Spring MVC(一)Servlet 2.x 规范在 Spring MVC 中的应用

    Spring MVC(一)Servlet 2.x 规范在 Spring MVC 中的应用 Spring 系列目录(https://www.cnblogs.com/binarylei/p/1019869 ...

  2. Spring 注解驱动(二)Servlet 3.0 注解驱动在 Spring MVC 中的应用

    Spring 注解驱动(二)Servlet 3.0 注解驱动在 Spring MVC 中的应用 Spring 系列目录(https://www.cnblogs.com/binarylei/p/1019 ...

  3. Spring mvc解析

    方案时间 ,写代码时间 ,解决技术难点时间 , 自测时间,解决bug时间 , 联调时间 ,数据库优化,代码走查1个接口:2个小时 把那个字段再复原回来,不然兼容性不强还有一个刷数据的接口 public ...

  4. Spring MVC如何获取请求中的参数

    目录 一.获取URL中路径参数 1.1 @PathVariable 注解 1.2 @PathParam 注解 二.获取请求参数: 2.1 GET请求 2.1.1 获取请求中的单个参数:@Request ...

  5. eclipse JavaEE spring,spring mvc,mybits-SSM老年人搭建记录

    老求了,好多东西记不住了,再不记以后怕是记不住了. eclipse JAVAEE for web Version: Mars.2 Release (4.5.2) tomcat 7.0.29 sprin ...

  6. 如何用Java类配置Spring MVC(不通过web.xml和XML方式)

    DispatcherServlet是Spring MVC的核心,按照传统方式, 需要把它配置到web.xml中. 我个人比较不喜欢XML配置方式, XML看起来太累, 冗长繁琐. 还好借助于Servl ...

  7. Spring MVC重定向和转发以及异常处理

    SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...

  8. Spring MVC入门

    1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...

  9. Spring7:基于注解的Spring MVC(下篇)

    Model 上一篇文章<Spring6:基于注解的Spring MVC(上篇)>,讲了Spring MVC环境搭建.@RequestMapping以及参数绑定,这是Spring MVC中最 ...

随机推荐

  1. ipa制作

    打包ipa步骤: 项目名称 -> edit scheme -> 如图选择release 点击close后,选择真机 然后command+b编译程序,右击app,show in Finder ...

  2. 经验总结:按需加载JS和css

    项目中做过这样的事情:所有页面都通过SSI指令 include这样一份public-js.shtml, 用来引入涉及到的js(包括公共的脚本 验证插件 自定义组件等),但是一些没有交互效果的页面根本不 ...

  3. Log Collect

    http://ossectools.blogspot.com/2011/03/comprehensive-log-collection.html https://www.hacking-lab.com ...

  4. Runtime.getRuntime().exec(...)使用方法

    Runtime.getRuntime().exec(...)使用方法 如果想要了解更多的信息,参阅代码里面给的链接  下面是这个正确的例子 public class RuntimeExec { /** ...

  5. __FILE__,__LINE__,FUNCTION__实现代码跟踪调试(linux下c语言编程 )

    root@xuanfei-desktop:~/cpropram/2# cat global.h //头文件#ifndef CLOBAL_H        #define GLOBAL_H        ...

  6. Part Acquisition(spfa输出路径)

    Part Acquisition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4080   Accepted: 1742 ...

  7. Dining(最大流)

    Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11844   Accepted: 5444 Descripti ...

  8. 64位CentOS上编译 Hadoop 2.2.0

    下载了Hadoop预编译好的二进制包,hadoop-2.2.0.tar.gz,启动起来后.总是出现这样的警告: WARN util.NativeCodeLoader: Unable to load n ...

  9. AlertDialog具体解释

    对话框介绍与演示样例         对话框在程序中不是必备的,可是用好对话框能对我们编写的应用增色不少.採用对话框能够大大添加应用的友好性.比較经常使用的背景是:用户登陆.网络正在下载.下载成功或者 ...

  10. BZOJ 2101: [Usaco2010 Dec]Treasure Chest 藏宝箱( dp )

    dp( l , r ) = sum( l , r ) - min( dp( l + 1 , r ) , dp( l , r - 1 ) ) 被卡空间....我们可以发现 l > r 是无意义的 ...