Spring MVC 遇到的一点点问题(转)

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

Java代码  

  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。

Java代码  

  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:

Java代码  

  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来解析

Java代码  

  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]

Java代码  

  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 里面提供的解决方案是将

Java代码  

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

改为

Java代码  

  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

时间: 2024-10-25 18:22:52

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

SI 系列入门 之 手把手构建 Spring MVC 工程

太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. SI 前文有述,Spring MVC + MyBatis 的简称,因为 Spring MVC 内部已有注入功能,故不考虑其是否是利用了 Sprin

《Spring实战》学习笔记-第七章:Spring MVC进阶

本章主要内容: 备用的Spring MVC配置项 处理文件上传 控制器中的异常处理 使用flash属性 "等等,客官!不止这些" 也许大家在看电视广告时对上面这句话比较熟悉,广告里通常在已经对商品做了完整的介绍,这时,电视里就会冒出这句:等等,客官,还不止这些...接着,就会继续吹嘘他们的商品还有更多让你意想不到的功能. 其实,Spring MVC(或者说Spring的每一个模块)就给人一种"不止这些"的感觉,就在你以为已经对Spring MVC的功能有了完备的了解

Swagger+ springfox +Spring mvc

简介 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步.Swagger 让部署管理和使用功能强大的API从未如此简单.这一次我将从零开始搭建一个工程来演示如何在Spring mvc中整合Swagger生成Restful接口文档. 新建工程 我们新建一个Maven工程,并添加Web Facet,工程结构如下图所

视图框架:Spring MVC 4.0(1)

目录 一.表单标签库 1.1.简介 1.2.常用属性 1.3.form标签与input标签 1.4.checkbox标签 1.5.radiobutton标签 1.6.password标签 1.7.select标签 1.8.option标签 1.9.options标签 1.10.textarea.errors标签 1.11.hidden标签 1.12.radiobuttons 单选列表与checkboxs复选列表 二.视图解析器 2.1.ViewResolver视图解析器 2.2.链式视图解析器

Spring MVC HTTP请求数据绑定

package com.springmvc.controller; import com.springmvc.model.UserInfo; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Controller; import org.springframework.uti

关于spring mvc的配置文件

1. Web.xml <!--配置页面控制器--> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</par

[转] 使用Spring MVC构建REST风格WEB应用

原文地址:http://fancy888.iteye.com/blog/1629120 对于运行在网络上的MIS系统而言,处理数据的是整个系统的主要任务,翻开程序我们可以看到,80%以上的代码都在处理数据的CRUD操作.采用一种什么样的框架结构,能够使得处理数据的操作变得简单且易理解,这是大部分开发者尤其是架构设计者一直以来思考的一个问题. REST(Representational State Transfer)是一种编程风格,特别是针对网络应用的设计和开发,采用REST可以显著降低开发的复杂

Spring MVC 基础

Spring MVC 基础 1.Web MVC基础 MVC的本质是表现层模式,我们以视图模型为中心,将视图和控制器分离出来.就如同分层模式一样,我们以业务逻辑为中心,把表现层和数据访问层代码分离出来是一样的方法.框架只能在技术层面上给我们帮助,无法在思考和过程上帮助我们,而我们很多人都不喜欢思考和尝试. 2.实现Web MVC的基础 实现Web MVC基础可以概括为1个前段控制器和2个映射. (1)前端控制器FrontController ASP.NET和JSP都是以Page路径和URL一一对应

spring MVC学习(一)---前端控制器

1.spring MVC中的前段控制器就是DsipatcherServlet,它在spring MVC框架中的结构图如下: 2.DispatcherServlet其实就是一个Servlet,它继承了HttpServlet这个抽象类. 先来看下该类在的位置: 为了使用它,你需要在你的web应用程序中的web.xml中配置一下,配置如下: <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class&