在springmvc controller和spring框架中,controller类可以被spring注入吗。

spring&MVC详解(转)
spring-mvc&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/6ea68-194d-ea4a786324.jpg" TITLE="点击查看原始大小图片" WIDTH="700" HEIGHT="371" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color: cursor: url(/images/magplus.gif),"
ALT="spring&MVC详解(转)" />
请求首先通过DispatcherServlet。servlet根据HandlerMapping,来处理请求,并根据请求,来找到Controller,Controller执行完毕后,发送一个ModelAndView,并告诉需要展示哪个视图。根据这个视图,servlet找到这个视图的ViewResolver,并由这个ViewResolver生成对应的view,并输出。&
配置servlet&
springmvc是基于servlet的,因此需要在web.xml配置。&
&servlet&&
&servlet-name&roadrantz&/servlet-name&&
&servlet-class&org.springframework.web.servlet.DispatcherServlet&
&/servlet-class&&
&load-on-startup&1&/load-on-startup&&
&/servlet&&
默认情况下,DispatcherServlet会加载这个servletname-servlet.xml文件,将这个文件作为spring的配置文件(淡然可以和全局的加载器,也就是全局的监听器和监听器加载的配置文件结合使用)。如上面我们定义的servlet-name的名字是roadrantz,因此它会加载roadrantz-servlet.xml。&
之后当然是要配置这个servlet对应的映射的了。&
&servlet-mapping&&
&servlet-name&roadrantz&/servlet-name&&
&url-pattern&*.htm&/url-pattern&&
&/servlet-mapping&&
事实上,我们应该把配置分成多个文件。这样,基于springmvc的配置只在servletname-servlet.xml中,和其他部分的配置(如事务管理,数据源等配置则在另外一个地方,因为他们是通用的)是分开的。&
WebApplicationContext&
WebApplicationContext是ApplicationContext的子类它提供了为WEB应用服务的更多功能。&
我们可以通过RequestContextUtils来获取WebApplicationContext&
DispatcherServlet&
会配置如下的bean&
Bean type Explanation&
controllers mvc中的C&
handler mappings 处理器影射器,它会根据请求,查找到实际的请求处理者&
view resolvers 视图解析器&
locale resolver 本地化解析器,提供国际化的支持&
Theme resolver 主题解析器&
multipart file 文件上传解析器&
handler exception resolvers 异常处理器&
DispatcherServlet配置完成后,当相应的请求到达时,处理就开始了。
处理流程是&
1.找到WebApplicationContext并将其绑定到请求的一个属性上,
以便控制器和处理链上的其它处理器能使用WebApplicationContext。
默认的属性名为DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE。&
2.将本地化解析器(localResolver)绑定到请求上,这样使得处理链上的处理器在处理请求(准备数据、显示视图等等)
时能进行本地化处理。若不使用本地化解析器,也不会有任何副作用,因此如果不需要本地化解析,忽略它即可。&
3.将主题解析器绑定到请求上,这样视图可以决定使用哪个主题。如果你不需要主题,可以忽略它,不会有任何影响。&
4.如果上传文件解析器被指定,Spring会检查每个接收到的请求是否存在上传文件,如果存在,
这个请求将被封装成MultipartHttpServletRequest以便被处理链中的其它处理器使用
(关于文件上传的更多内容请参考Section 13.8.2,
“使用MultipartResolver”)。&
5.找到合适的处理器,执行和这个处理器相关的执行链(预处理器,后置处理器,控制器),以便为视图准备模型数据(用于渲染)。&
6.如果模型数据被返回,就使用配置在WebApplicationContext中的视图解析器显示视图,
否则视图不会被显示。有多种原因可以导致返回的数据模型为空,比如预处理器或后处理器可能截取了请求,这可能是出于安全原因,
也可能是请求已经被处理,没有必要再处理一次。&
DispatcherServlet的初始化参数&
contextClass
实现了WebApplicationContext的类。默认是XmlWebApplicationContext。&
contextConfigLoSctraintgitohnat
与全局的contextConfigLoSctraintgitohnat参数可以共存&
WebApplicationContext的命名空间。默认是[servlet-name]-servlet&
多个配置文件的方式&
1.基于监听器的方式:&
定义监听器&
&listener&&
&listener-class&org.springframework.&
web.context.ContextLoaderListener&/listener-class&&
&/listener&&
以及配置全局监听器的配置属性。&
有些比较老的容器,在初始化servlet之前,并不会初始化监听器,因此如果可能会被部署到这样的容器的话,需要将监听器,改成另外一个servlet&
ContextLoaderServlet&
将它置于DispatcherServlet之前。&
不管是监听器还是ContextLoaderServlet,这两个全局的装载器,在没有指定配置文件的情况下,会查找/WEB-INF/applicationContext.xml。&
但我们会有更多的配置文件,可以通过属性contextConfigLocation来设置&
&context-param&&
&param-name&contextConfigLocation&/param-name&&
&param-value&&
/WEB-INF/spitter-security.xml&
classpath:service-context.xml&
classpath:persistence-context.xml&
classpath:dataSource-context.xml&
&/param-value&&
&/context-param&&
这个属性的值,和spring的资源Resource加载方式一样,可以带classpath:,file:,等前缀。&
这里先给出一个非注解方式的使用方式。&
主页是一个web应用必须有的(这里说的必须,你懂得)。&
当然先需要一个controller了。&
package com.roadrantz.&
import java.util.L&
javax.servlet.http.HttpServletR&
javax.servlet.http.HttpServletR&
org.springframework.web.servlet.ModelAndV&
org.springframework.web.servlet.mvc.AbstractC&
import com.roadrantz.service.RantS&
public class HomePageController extends AbstractController
public HomePageController() {&
protected ModelAndView
handleRequestInternal(&
HttpServletRequest request, HttpServletResponse
response)&
throws Exception {&
List recentRants =
rantService.getRecentRants();&
//定义modelandview,home表示会返回home.jsp(是不是jsp由视图解析器决定)。&
return new ModelAndView("home",&
"rants", recentRants);&
private RantService rantS&
public void setRantService(RantService rantService)
this.rantService = rantS&
ModelAndView对象&
ModelAndView封装了视图已经模型数据。&
注意,如果一个controller,return类型非null或者非viod,且没有写@ResponseBody注解的,最后都会被封装成ModelAndView,对与返回的一个普通的bean的时候,分装后的ModelAndView如下图&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/17e5d-d9fd-353c-833f8.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
new ModelAndView("home", "rants",
recentRants);&
如上,第一个参数是视图名字。之后的参数是以模型对象将被传递给视图。&
下面是配置这个controller&
&bean name="/home.htm"&
class="com.roadrantz.mvc.HomePageController"&&
&property name="rantService" ref="rantService"
这里首先没有使用id,而是使用name,这里的原因是因为有特殊字符/和.id不支持。而使用name。&
当一个请求home.htm(这个请求位于根目录下,如果非根目录是无法访问的,如127.0.0.1/daowole/home.htm是可以访问的,但是127.0.0.1/daowole/abc/home.htm是无法访问的。如果想要它不管通过哪个目录,只要是最后的资源是home.htm都可以访问,可以把bean的name改成name="home.htm",那么127.0.0.1/daowole/abc/home.htm还是127.0.0.1/daowole/home.htm都可以访问了。)的话,那么就会被访问到这里来。这里可以发现我们无需配置HandlerMapping,因为springmvc有一个默认的handlermapping,BeanNameUrlHandlerMapping。它是使用URL模式的基本名字。&
由于上面的的视图使用的是jsp视图,因此直接return一个jsp页面,自然没有问题了。&
而对应jsp视图,springmvc自然还提供了其他配置(相对普通jsp而言),这需要使用到一个jsp的解析器,org.springframework.web.servlet.view.InternalResourceViewResolver。&
&bean id="viewResolver"&
class="org.springframework.web.&
servlet.view.InternalResourceViewResolver"&&
name="prefix"&&
&value&/WEB-INF/jsp/&/value&&
&/property&&
name="suffix"&&
&value&.jsp&/value&&
&/property&&
这个会再controller返回的时候,会拼装前缀和后缀,再查找文件。如果找到,它来处理是自然的。&
home拼装前缀和后缀后就是/WEB-INF/jsp/home.jsp&
对于spring3.0版本的,如果使用了Spring
3.0.4或以上版本的话,可以使用&
&mvc:resources location=""
mapping=""/&&
在servletname-servlet.xml文件中。&
这种情况就解决了如果我们把url映射定义为/(这会由springmvc处理所有的请求),那么图片,js等静态资源会被由springmvc处理。它会把mapping指定的路径(ant风格)映射到location中。&
&mvc:resources
mapping="/resources&
public class HelloController&
&&& extends
AbstractCommandController {&
&bean id="urlMapping"&
class="org.springframework.web.servlet.monsPathMapHandlerMapping"
SimpleUrlHandlerMapping&
&bean id="simpleUrlMapping"&
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&&
name="mappings"&&
key="test.html"&homeController&/prop&&
&/property&&
如上,当任何一种方式访问到test.html,都由id=homeController的bean处理&
mappings是一个java.util.Properties类型的。&
ControllerClassNameHandlerMapping使用&
package com.cgodo.daowole.&
javax.servlet.http.HttpServletR&
javax.servlet.http.HttpServletR&
org.springframework.web.servlet.ModelAndV&
org.springframework.web.servlet.mvc.AbstractC&
public class SampleController extends AbstractController
protected ModelAndView handleRequestInternal(HttpServletRequest
HttpServletResponse arg1) throws Exception
ModelAndView mav = new
ModelAndView("index");&
mav.addObject("message", "Hello World!");&
&bean id="urlMapping"&
class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"
如上,我们可以通过test.html(这里的后缀.html和你的web.xml配置有关)。就能访问。而不需要再增加其他的配置了。&
DefaultAnnotationHandlerMapping
根据@RequestMapping注解要查找action&
对于支持DefaultAnnotationHandlerMapping
版本的spring,如果没有对应&
handlermapping,那么DispatcherServlet会分别建立&
BeanNameUrlHandlerMapping&
DefaultAnnotationHandlerMapping&
多个handlemapping同时处理,也是可以的。我们也可以通过order属性。来配置mapping的排序。&
&bean id="beanNameUrlMapping"
class="org.springframework.web.&
servlet.handler.BeanNameUrlHandlerMapping"&&
name="order"&&value&1&/value&&/property&&
&bean id="simpleUrlMapping"
class="org.springframework.web.&
servlet.handler.SimpleUrlHandlerMapping"&&
name="order"&&value&0&/value&&/property&&
name="mappings"&&
&/property&&
这里的话,SimpleUrlHandlerMapping排序是0,因此它首先被servlet询问,如果这个SimpleUrlHandlerMapping有结果回来(标示它来处理),那么就进行处理,而没有的话,将询问下一个,也就是BeanNameUrlHandlerMapping。&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/495693/ad5e-36c1-8ad7-.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
如图,spring的控制器,由Controller接口定义。&
可以将控制器归类为6类&
View类型:&
ParameterizableViewController&
UrlFilenameViewController&
当控制器只需要显示静态视图时。&
Simple类型&
Controller (interface)&
AbstractController&
Throwaway类型&
ThrowawayController&
Multiaction类型&
MultiActionController&
当action中有多个执行代码(方法)。&
Command类型&
BaseCommandController&
AbstractCommandController&
action可以获取请求的一个或多个参数,并将参数封装成一个对象。还能对参数进行验证。&
AbstractFormController&
SimpleFormController&
拥有表单处理功能。&
Wizard类型&
AbstractWizardFormController&
当一个应用,由多个步骤组成,每一个步骤走完之后,得到一个结果,类似向导。&
AbstractCommandController&
直接继承AbstractController,自然可以访问到request,来获取参数,完成参数验证,但是这样会让你的action变得复杂。&
package com.cgodo.daowole.&
javax.servlet.http.HttpServletR&
javax.servlet.http.HttpServletR&
org.springframework.validation.BindE&
org.springframework.web.servlet.ModelAndV&
org.springframework.web.servlet.mvc.AbstractCommandController;&
import com.cgodo.daowole.model.P&
@SuppressWarnings("deprecation")&
public class SampleController extends AbstractCommandController
public SampleController() {&
setCommandClass(Page.class);&
setCommandName("page");&
@SuppressWarnings("unchecked")&
protected ModelAndView handle(HttpServletRequest
HttpServletResponse response, Object command, BindException
throws Exception {&
ModelAndView mav = new ModelAndView("index", "message",
"hello!");&
@SuppressWarnings("unused")&
Page&String& page =
(Page&String&)
如上所示。&
http://127.0.0.1:8080/daowole/test.html?pageNo=2&
可以发现,pageNo被注入到了command变量中。&
编写验证类&
package com.cgodo.daowole.action.&
org.springframework.validation.E&
org.springframework.validation.V&
import com.cgodo.daowole.model.P&
public class PageValidator implements Validator
public boolean supports(Class&?&
return arg0.equals(Page.class);&
public void validate(Object command, Errors arg1)
Page&String& page =
(Page&String&)
if (page.getPageNo() & 2) {&
arg1.rejectValue("pageNO", "request.pageNo",
"请输入pageNo");&
修改bean的定义&
&bean id="homeController"
name="home.html"&
class="com.cgodo.daowole.action.SampleController"&&
&property name="formView" value="input"
&property name="successView" value="index"
name="validator"&&
class="com.cgodo.daowole.action.validator.PageValidator"
&/property&&
SimpleFormController&
package com.roadrantz.&
import java.util.HashM&
import java.util.M&
javax.servlet.http.HttpServletR&
org.springframework.validation.BindE&
org.springframework.web.servlet.ModelAndV&
org.springframework.web.servlet.mvc.SimpleFormC&
import com.roadrantz.domain.R&
import com.roadrantz.domain.V&
import com.roadrantz.service.RantS&
public class AddRantFormController extends SimpleFormController
private static final String[] ALL_STATES =
"AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC",
"GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA",
"MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV",
"NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA",
"SC", "SD", "TN", "TX", "UT", "VA", "VT", "WA", "WV",
public AddRantFormController() {&
setCommandClass(Rant.class);&
setCommandName("rant");&
protected Object formBackingObject(HttpServletRequest
throws Exception {&
Rant rantForm = (Rant)
super.formBackingObject(request);&
rantForm.setVehicle(new Vehicle());&
return rantF&
protected Map referenceData(HttpServletRequest
throws Exception {&
Map referenceData = new HashMap();&
referenceData.put("states", ALL_STATES);&
return referenceD&
protected ModelAndView onSubmit(Object
BindException bindException) throws Exception
Rant rant = (Rant)&
rantService.addRant(rant);&
return new ModelAndView(getSuccessView());&
private RantService rantS&
public void setRantService(RantService rantService)
this.rantService = rantS&
&bean id="addRantController"&
class="com.roadrantz.mvc.AddRantFormController"&&
&property name="formView" value="addRant"
&property name="successView" value="rantAdded"
&property name="rantService" ref="rantService"
编写验证类&
package com.roadrantz.&
import org.apache.oro.text.perl.Perl5U&
org.springframework.validation.E&
org.springframework.validation.ValidationU&
org.springframework.validation.V&
import com.roadrantz.domain.R&
public class RantValidator implements Validator
public boolean supports(Class clazz) {&
return clazz.equals(Rant.class);&
public void validate(Object command, Errors errors)
Rant rant = (Rant)&
ValidationUtils.rejectIfEmpty(&
errors, "vehicle.state", "required.state",&
"State is required.");&
ValidationUtils.rejectIfEmpty(&
errors, "vehicle.plateNumber",
"required.plateNumber",&
"The license plate number is required.");&
ValidationUtils.rejectIfEmptyOrWhitespace(&
errors, "rantText", "required.rantText",&
"You must enter some rant text.");&
validatePlateNumber(&
rant.getVehicle().getPlateNumber(),
private static final String PLATE_REGEXP =&
"/[a-z0-9]{2,6}/i";&
private void validatePlateNumber(&
String plateNumber, Errors errors) {&
Perl5Util perl5Util = new Perl5Util();&
if(!perl5Util.match(PLATE_REGEXP, plateNumber))
errors.reject("invalid.plateNumber",&
"Invalid license plate number.");&
修改bean的定义。&
&bean id="addRantController"&
class="com.roadrantz.mvc.AddRantFormController"&&
&property name="formView" value="addRant"
&property name="successView" value="rantAdded"
&property name="rantService" ref="rantService"
name="validator"&&
&bean class="com.roadrantz.mvc.RantValidator"
&/property&&
package com.cgodo.daowole.service.&
org.springframework.stereotype.S&
import com.cgodo.daowole.service.IT&
public class MyTest implements ITest {&
public void test() {&
package com.cgodo.daowole.&
org.springframework.beans.factory.annotation.A&
org.springframework.stereotype.C&
org.springframework.web.bind.annotation.RequestM&
import com.cgodo.daowole.service.IT&
@Controller&
public class ActionTest {&
private IT&
public ITest getTest() {&
@Autowired&
public void setTest(ITest test) {&
this.test =&
@RequestMapping(value = "/")&
public String home() {&
System.out.println("HomeController: Passing
through...");&
return "index";&
@RequestMapping("/input")&
public String input(String input) {&
System.out.println("name is " + input);&
return "index";&
com.cgodo.daowole.spring.applicationContext包下面&
applicationContext.xml&
&?xml version="1.0"
encoding="UTF-8"?&&
xmlns="http://www.springframework.org/schema/beans"&
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"&
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"&
xsi:schemaLocation="http://www.springframework.org/schema/beans&
&&&&&&&&&&
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&
&&&&&&&&&&
http://www.springframework.org/schema/context&
&&&&&&&&&&
http://www.springframework.org/schema/context/spring-context-2.5.xsd&
&&&&&&&&&&
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd&
&&&&&&&&&&
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"&&
&!-- 开启注解支持
,将会对注解进行处理--&&
&context:annotation-config
开启自动代理,自动代理是指Spring会判断一个bean是否使用了一个或多个切面通知,并据此自动生成相应的代理以拦截其方法调用,并且确认通知是否如期进行。&
如果想强制使用CGLIB代理,需要将
&aop:aspectj-autoproxy& 的
proxy-target-class&
属性设为true。&
&aop:aspectj-autoproxy proxy-target-class="true"
&!-- 扫描的包,spring将自动扫描这些包,根据其的注解配置,自动进行配置
&context:component-scan&
base-package="com.cgodo.daowole.dao, com.cgodo.daowole.service,
com.cgodo.daowole.aop" /&&
&!-- 注解驱动开启,对注解方式的事物进行支持
&tx:annotation-driven mode="aspectj"
&!-- 数据源配置
&bean id="dataSource"
class="mons.dbcp.BasicDataSource"&
destroy-method="close"&&
&property name="driverClassName"
value="com.mysql.jdbc.Driver"
&property name="url"&
value="jdbc:mysql://10.13.166.224:3306/daowole?useUnicode=false&autoReconnect=true&characterEncoding=utf-8"
&property name="username" value="root"
&property name="password" value=""
&!-- 事物管理员
id="transactionManager"&
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&&
&property name="dataSource" ref="dataSource"
WEB-INF文件夹下面&
springMVC-servlet.xml&
&?xml version="1.0"
encoding="UTF-8"?&&
xmlns="http://www.springframework.org/schema/beans"&
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"&
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"&
xsi:schemaLocation="http://www.springframework.org/schema/beans&
&&&&&&&&&&
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&
&&&&&&&&&&
http://www.springframework.org/schema/context&
&&&&&&&&&&
http://www.springframework.org/schema/context/spring-context-2.5.xsd&
&&&&&&&&&&
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd&
&&&&&&&&&&
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"&
default-&&
&context:component-scan
base-package="com.cgodo.daowole.action"
&mvc:annotation-driven
class="org.springframework.web.servlet.view.InternalResourceViewResolver"&&
&property name="prefix" value=""
&property name="suffix" value=".jsp"
&?xml version="1.0"
encoding="UTF-8"?&&
&web-app id="WebApp_ID"
version="2.4"&
xmlns="/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&
xsi:schemaLocation="/xml/ns/j2ee
/xml/ns/j2ee/web-app_2_4.xsd"&&
&display-name&daowole&/display-name&&
&context-param&--&&
&param-name&contextConfigLocation&/param-name&--&&
&param-value&&/param-value&--&&
&/context-param&--&&
&listener&--&&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&&
&/listener&--&&
&servlet&&
&description&&
test&/description&&
&display-name&test&/display-name&&
&servlet-name&test&/servlet-name&&
&servlet-class&com.cgodo.daowole.test.ServletTest&/servlet-class&&
&/servlet&&
&servlet&&
&servlet-name&springMVC&/servlet-name&&
&servlet-class&org.springframework.web.servlet.DispatcherServlet&/servlet-class&&
&init-param&&
&param-name&contextConfigLocation&/param-name&&
&param-value&/WEB-INF/springMVC-servlet.xml,
classpath:com/cgodo/daowole/spring/applicationContext/applicationContext.xml&/param-value&&
&/init-param&&
&load-on-startup&1&/load-on-startup&&
&/servlet&&
&servlet-mapping&&
&servlet-name&test&/servlet-name&&
&url-pattern&/test&/url-pattern&&
&/servlet-mapping&&
&servlet-mapping&&
&servlet-name&springMVC&/servlet-name&&
&url-pattern&home.do"
public String home(&
@RequestParam(value = "name", required = false) String
username,&
Model model) {&
System.out.println("------------------------------");&
System.out.println("userName is " +
username);&
System.out.println("------------------------------");&
model.addAttribute(new
Page&String&());&
return "index";&
请求中的参数name必须输入(required = true,如果没有@RequestParam,默认required =
false,如果写了@RequestParam,默认required = true)&
另外注意在类得上面有@RequestMapping("/test"),表示,只有再请求是资源位于/test下面才会处理&
比如(应用是daowole)&
127.0.0.1/daowole/abc/home.do&
127.0.0.1/daowole/abc/test/home.do&
127.0.0.1/daowole/&
127.0.0.1/daowole/abc/&
将不被处理,&
127.0.0.1/daowole/test/home.do&
127.0.0.1/daowole/test/&
如果去掉上面的类注解@RequestMapping("/test"),那么&
127.0.0.1/daowole/abc/&
127.0.0.1/daowole/test/&
将不被处理&
127.0.0.1/daowole/abc/home.do&
127.0.0.1/daowole/abc/test/home.do&
127.0.0.1/daowole/&
127.0.0.1/daowole/test/home.do&
另外一个参数是Model,它是模型处理器。&
model.addAttribute(new
Page&String&());将根据传入的对象的类型,生成对应的attribute
name,比如Page类型生成page,而Account生成account,AccountOther生成accountOther。&
@RequestParam注解并非必须。当请求参数名和方法参数名字不相同的时候,才需要。如果不是用这个注解,那么将自动把请求参数名映射到对应的方法参数名。&
另外我们的model是用的是Model接口,而不是Map&String,
Object&,这是因为Model接口提供了更方便的功能。&
package com.cgodo.daowole.&
org.springframework.stereotype.C&
import org.springframework.ui.M&
org.springframework.web.bind.annotation.RequestM&
org.springframework.web.bind.annotation.RequestP&
import com.cgodo.daowole.model.P&
@Controller&
@RequestMapping("/test")&
public class AnnotationAction {&
@RequestMapping( { "/", "home.do" })&
public String home(String pageSize, Model model,
Page&String& page)
System.out.println("------------------------------");&
System.out.println("userName is " +
pageSize);&
System.out.println("------------------------------");&
model.addAttribute(new
Page&String&());&
return "redirect:input.jsp";&
上面的代码中,首先要知道Page类型里面有一个pageSize属性,另外我们方法中也定义了一个pageSize参数。这个时候如果我们请求中有pageSize参数,那么方法参数的pageSize属性和page对象里面的pageSize属性的值会同时被设置为这个请求参数的值。&
另外需要看的是return
"redirect:input.jsp";这里有一个redirect:前缀,表示重定向到input.jsp。&
package com.cgodo.daowole.&
org.springframework.stereotype.C&
import org.springframework.ui.M&
org.springframework.web.bind.annotation.PathV&
org.springframework.web.bind.annotation.RequestM&
import com.cgodo.daowole.model.P&
@Controller&
@RequestMapping("/my")&
public class AnnotationAction {&
@RequestMapping( { "/", "home.do" })&
public String home(String pageSize, Model model,
Page&String& page)
System.out.println("------------------------------");&
System.out.println("userName is " +
pageSize);&
System.out.println("------------------------------");&
model.addAttribute(new
Page&String&());&
return "redirect:input.jsp";&
@RequestMapping( { "/{name}/{cask}" })&
public String home(@PathVariable String name, String pageSize,
Model model,&
Page&String& page, @PathVariable
String cask) {&
System.out.println("------------------------------");&
System.out.println("userName is " +
pageSize);&
System.out.println("------------------------------");&
model.addAttribute(new
Page&String&());&
return "redirect:input.jsp";&
看另一个方法home&
@RequestMapping( { "/{name}/{cask}" })&
{varName}会将/my/后面的路径转化成参数。&
最后一个{varName}会自动去掉后缀。&
@RequestMapping( { "/{name}/{cask}"
})写了两个varName,因此必须存在两个目录级别(相对@RequestMapping("/my")而言)。由于只写了两级varName,因此也必须只有两级,三级的话就无效了。&
PathVariable 默认根据参数名字和请求参数名自动映射(名字相同)。&
可以根据自己的名字&
@RequestMapping( { "/{test}/{cask}" })&
public String home(@PathVariable("test") String name, String
pageSize, Model model,&
Page&String& page, @PathVariable
String cask) {&
System.out.println("------------------------------");&
System.out.println("userName is " +
pageSize);&
System.out.println("------------------------------");&
model.addAttribute(new
Page&String&());&
return "redirect:input.jsp";&
它也支持ant路径风格&
如果定义了类级别的RequestMapping路径参数风格,在方法级别那可以指定更详细的规则&
package com.cgodo.daowole.&
org.springframework.stereotype.C&
import org.springframework.ui.M&
org.springframework.web.bind.annotation.PathV&
org.springframework.web.bind.annotation.RequestM&
@Controller&
@RequestMapping("/owners/{ownerId}")&
public class ControllerTest {&
@RequestMapping(value = "/pets/{petId}", params =
"myParam=myValue")&
public void findPet(@PathVariable String
@PathVariable String petId, Model model) {&
System.out.println();&
@RequestMapping(value = "/", headers = "content-type=texthome.do"
public String home(String pageSize, Model model,
Page&String&
BindingResult bindingResult,&
@RequestParam(value = "image", required = false) MultipartFile
System.out.println("------------------------------");&
System.out.println("userName is " +
pageSize);&
System.out.println("------------------------------");&
model.addAttribute(new
Page&String&());&
return "redirect:input.jsp";&
@RequestMapping( { "/a/{name}/{cask}" })&
public String home(@PathVariable String name, String pageSize,
Model model,&
Page&String& page, @PathVariable
String cask) {&
System.out.println("------------------------------");&
System.out.println("userName is " +
pageSize);&
System.out.println("------------------------------");&
model.addAttribute(new
Page&String&());&
return "redirect:input.jsp";&
@RequestParam(value = "image", required = false) MultipartFile
发现@RequestParam去掉,就报错,&
beans.BeanInstantiationException: Could not instantiate bean class
[org.springframework.web.multipart.MultipartFile]:&
Specified class is an interface&
而留下这句就不会报错,不知道什么原因。。。&
减少到最小&
@RequestParam&
到这种程度。&
DispatcherServlet的不知道如何处理多部分&
表单数据。我们需要一个multipart解析器来提取出的多重数据&
DispatcherServlet的POST请求,以便它可以给我们的控制器。&
要注册一个Spring multipart解析器,我们只需要声明一个bean,&
实现了MultipartResolver接口。&
spring提供了一个实现&
CommonsMultipartResolver&
&mvc:annotation-driven
/&后这个类会自动注入。当然我们如果要配置更多的属性,需要自己定义这个bean&
&bean id="multipartResolver"&
class="org.springframework.monsMultipartResolver"&&
&property name="maxUploadSize"
value="5000000"&&/property&&
注意这里的bean
id是固定的。spring会自动读取一个叫做multipartResolver的bean。如果叫做其他名字是无效的。&
关于action的返回值和参数&
RequestMapping注解定义的方法,这个方法的参数和返回值定义可以很灵活。下面说的参数可以定义任意数量。&
1.可以在方法中定义Request和Response,类型可以是ServletRequest 或
HttpServletRequest.&
response类似&
2.Session对象,类型HttpSession.session是线程不安全的。可以在定义的AnnotationMethodHandlerAdapter中的参数synchronizeOnSession设置为true,来设置为线程安全的。&
3.org.springframework.web.context.request.WebRequest类型或者org.springframework.web.context.request.NativeWebRequest类型的Servlet/Portlet
4.java.util.Locale 获取当前请求的本地信息。&
5.java.io.InputStream /
java.io.Reader类型,可以获取到请求的输入流&
6.java.io.OutputStream /
java.io.Writer类型可以获取到回应的输出流。&
7.java.security.Principal 当前的验证用户&
8.在参数之前加入@PathVariable注解。来处理目录影射为参数值&
9.在参数之前加入@RequestParam注解。来处理从参数影射为方法参数值&
10.在参数之前加入@RequestHeader注解。用来将指定的请求头信息影射为方法的参数。&
11.在参数之前加入@RequestBody注解。用来将指定的客户端发送过来的请求参数的数据格式转换成java实体&
12.定义一个HttpEntity&?&类型的变量。将会把请求参数的head和请求内容转换成实体类。&
13.java.util.Map / org.springframework.ui.Model
/org.springframework.ui.ModelMap&
这个是存放数据模型的。&
14.命令,或表单对象的实体。会将请求参数转成实体。@InitBinder注解或者HandlerAdapter
定义的时候进行转换设置。&
15.org.springframework.validation.Errors/org.springframework.validation.BindingResult验证结果。&
16.org.springframework.web.bind.support.SessionStatus
需要注意的是,Errors类型和BindingResult类型的参数的排序一定要有规则。&
因为定义的实体模型可能有多个,spring会为每个实体创建org.springframework.validation.Errors/org.springframework.validation.BindingResult&
如果定义的org.springframework.validation.Errors/org.springframework.validation.BindingResult类型排序不对应了,那么可能会无法得到你的预期结果&
@RequestMapping(method =
RequestMethod.POST)&
public String processSubmit(@ModelAttribute("pet") Pet
Model model, BindingResult result) { … }&
这里的result对应的是model,而不是pet。&
@RequestMapping(method =
RequestMethod.POST)&
public String processSubmit(@ModelAttribute("pet") Pet
BindingResult result, Model model) { … }&
这个是有效的。&
控制器的返回结果&
1.ModelAndView
包含了@ModelAttribute注解定义的key=@ModelAttribute("a")的value=模型的结果,视图名,命令对象。&
2.Model对象,包含了视图名(RequestToViewNameTranslator类型),模型数据,命令对象,和ModelAttribute注解定义的模型。&
3.Map对象,和Model类似。&
4.View对象,包含了命令对象,@ModelAttribute注解定义的模型。可能还包含了Model对象。&
5.String字符串。一个逻辑视图名。&
6.void 当结果直接写入ServletResponse /
HttpServletResponse。requestToViewNameTranslator将自动查找视图。
7.如果这个方法定义了@ResponseBody注解。那么会把返回值转换成这个数据格式,输出给客户端。&
8.HttpEntity&?&类型或者ResponseEntity&?&,会将返回值转换成响应的head和响应内容。&
9.其他任何类型。&
@RequestParam&
@Controller&
@RequestMapping("/pets")&
@SessionAttributes("pet")&
public class EditPetForm {&
@RequestMapping(method = RequestMethod.GET)&
public String setupForm(@RequestParam("petId") int petId, ModelMap
Pet pet = this.clinic.loadPet(petId);&
model.addAttribute("pet", pet);&
return "petForm";&
先看@RequestMapping,它指定了影射的关系。&
在看SessionAttributes注解,其作用看后面内容。&
@RequestParam("petId")&
这里定义了从请求参数映射到方法参数的映射关系。直接写一个字符串表示将请求参数的petId映射为方法参数的第一个参数。&
RquestBody注解&
这个可以将http的请求 body转换成指定格式。&
注意 http协议中,Request
body只有在post格式提交的数据,才用户请求体(put,head等请求方式,很少使用,我们不考虑)。而get请求方式没有Request
Body。详情请了解http协议&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/3a45f-e283-323e-accd-a7.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
注意这里的转换和方法的参数名无关系。&
编写如下内容&
&!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"&&
&meta http-equiv="Content-Type" content="text/
charset=UTF-8"&&
&title&领钱&/title&&
&form action="test/body"
method="post"&&input&
name="body" value="123" /& &input
name="name" value="456"
type="submit"
/&&/form&&
package com.cgodo.daowole.&
import java.io.IOE&
import java.io.W&
org.springframework.stereotype.C&
import org.springframework.ui.M&
org.springframework.web.bind.annotation.PathV&
org.springframework.web.bind.annotation.RequestB&
org.springframework.web.bind.annotation.RequestM&
@Controller&
@RequestMapping("/test")&
public class ControllerTest {&
@RequestMapping(value = "/pets/{petId}", params =
"myParam=*")&
public void findPet(@PathVariable String
@PathVariable String petId, Model model) {&
System.out.println();&
@RequestMapping(value = "/body")&
public void handle(@RequestBody() String host, Writer
throws IOException {&
writer.write(host);&
http://127.0.0.1:8081/daowole/index.jsp&
并点击提交。请求体将被获得,我们还把请求体答应出去了。&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/497323/cd29a21c-34c5-3787-ab54-cae0.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
这里的请求体转换是通过&
HttpMessageConverter实现类来完成的。&
基于注解的mvc使用DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter.(spring
AnnotationMethodHandlerAdapter提供了对RequestBody注解的支持。&
提供实现的转换器&
ByteArrayHttpMessageConverter 转换byte数组&
StringHttpMessageConverter 转换成String&
FormHttpMessageConverter
将请求体转换成一个MultiValueMap&String,
SourceHttpMessageConverter
转换javax.xml.transform.Source.我使用的时候报错,不知道是不是需要添加其他东西的支持&
MarshallingHttpMessageConverter
转换成org.springframework.oxm下面的类&
AnnotationMethodHandlerAdapter默认加上上面的内容的bean&
另外,对于AnnotationMethodHandlerAdapter在处理requestbody注解之前,有request.getParameter(String
name);方法的话,会破坏对post的body的处理,也就是会再它处理之前,把request的inputstream读取完毕了。(至于原因查看http协议)。如主题修改拦截器,本地化拦截器都会在它之前执行request.getParameter(String
name);。那么就会是都最后得到的requestBody的结果为null。&
@ResponseBody注解&
这个注解可以放在一个方法的声明那,当方法返回时,将返回的内容直接写入到请求的客户端,而不是作为一个视图。&
package com.cgodo.daowole.&
import java.io.IOE&
import java.io.W&
org.springframework.stereotype.C&
import org.springframework.ui.M&
org.springframework.util.MultiValueM&
org.springframework.web.bind.annotation.PathV&
org.springframework.web.bind.annotation.RequestB&
org.springframework.web.bind.annotation.RequestM&
org.springframework.web.bind.annotation.ResponseB&
@Controller&
@RequestMapping("/test")&
public class ControllerTest {&
@RequestMapping(value = "/pets/{petId}", params =
"myParam=*")&
public void findPet(@PathVariable String
@PathVariable String petId, Model model) {&
System.out.println();&
@RequestMapping(value = "/body")&
public void handle(@RequestBody()
MultiValueMap&String, String&
Writer writer) throws IOException {&
writer.write("");&
@RequestMapping(value = "/responseBody")&
@ResponseBody&
public String responseBody() {&
return "Hello World";&
responseBody方法使用这个注解。&
将直接输出hello world给客户端。&
http://127.0.0.1:8081/daowole/test/responseBody&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/caac7-6f3d-35cf-803d-7.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
当然直接输出的内容可能会照成部分浏览器无法解析的问题。这要看浏览器的严格程度。&
HttpEntity&?&
ResponseEntity&?&&
ResponseEntity是HttpEntity子类,专门用于处理响应的。&
和@requestbody和@responsebody类似(既然类似,和他们一样需要post)&
package com.cgodo.daowole.&
import java.io.IOE&
java.io.UnsupportedEncodingExcep&
import java.io.W&
import org.springframework.http.HttpE&
org.springframework.http.HttpH&
import org.springframework.http.HttpS&
org.springframework.http.ResponseE&
org.springframework.stereotype.C&
import org.springframework.ui.M&
org.springframework.util.MultiValueM&
org.springframework.web.bind.annotation.PathV&
org.springframework.web.bind.annotation.RequestB&
org.springframework.web.bind.annotation.RequestM&
org.springframework.web.bind.annotation.ResponseB&
@Controller&
@RequestMapping("/test")&
public class ControllerTest {&
@RequestMapping(value = "/pets/{petId}", params =
"myParam=*")&
public void findPet(@PathVariable String
@PathVariable String petId, Model model) {&
System.out.println();&
@RequestMapping(value = "/body")&
public void handle(@RequestBody()
MultiValueMap&String, String&
Writer writer) throws IOException {&
writer.write("");&
@RequestMapping(value = "/responseBody")&
@ResponseBody&
public String responseBody() {&
return "Hello World";&
@RequestMapping("/entity")&
public ResponseEntity&String&
handle(HttpEntity&String&
requestEntity)&
throws UnsupportedEncodingException {&
String requestHeader =
requestEntity.getHeaders().getFirst(&
"MyRequestHeader");&
String requestBody =
requestEntity.getBody();&
// do something with request header and
HttpHeaders responseHeaders = new
HttpHeaders();&
responseHeaders.set("MyResponseHeader",
"MyValue");&
return new
ResponseEntity&String&("Hello World",
responseHeaders,&
HttpStatus.CREATED);&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/497347/aa577e63-1cf8--cd6bed3ac895.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
结果如上图&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/c-37be-bfe7-cdd.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
@ModelAttribute注解&
可以用在方法声明上面,或者方法参数声明的时候。注意声明在方法之前的@ModelAttribute注解(假设这个方法没有RequestMapping),将会在@RequestMapping定义了的方法之前执行一遍(如果@ModelAttribute和ModelAttribute和@RequestMapping不在同一个方法),然后再执行匹配的方法。如果@ModelAttribute和@RequestMapping在一个方法都存在。不会在其他方法之前执行。&
@ModelAttribute("types")&
public Collection&String&
populatePetTypes() {&
List&String& ss = new
ArrayList&String&();&
@RequestMapping("/model")&
public String processSubmit() {&
return "index";&
如上populatePetTypes方法是没有的RequestMapping,请求&
http://127.0.0.1:8081/daowole/test/model,先执行&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/fef8f6-faac--26f1a0eb6cc7.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/bb9a0be-8f6e-3168-af4a-37a2e489cb36.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
@ModelAttribute("types")&
@RequestMapping("/model1.do")&
public Collection&String&
populatePetTypes() {&
List&String& ss = new
ArrayList&String&();&
@RequestMapping("/model")&
public String processSubmit() {&
return "index";&
访问http://127.0.0.1:8081/daowole/test/model&
直接进入processSubmit,无需先执行populatePetTypes&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/bc0a1c-2ff5-8557591cde.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
http://127.0.0.1:8081/daowole/test/model1.do&
进入populatePetTypes&
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/upload/attachment/c6b48a-f318-3bc5-bbde-dd.jpg" STYLE="border-top-width: 0 border-right-width: 0 border-bottom-width: 0 border-left-width: 0 border-style: border-color:"
ALT="spring&MVC详解(转)"
TITLE="spring&MVC详解(转)" />
@SessionAttributes注解&
写在类级别的注解,定义一个session
attributes,属性名字为SessionAttributes指定。可以指定多个(数组),也同时可以指定类型。&
@Controller&
@SessionAttributes( { "user" })&
@RequestMapping("/test")&
public class ControllerTest {&
@RequestMapping("/session")&
@ResponseBody&
public String sessionIn(@ModelAttribute("user") User user)
return "index";&
@RequestMapping("/sessionOut")&
@ResponseBody&
public String sessionOut(HttpSession session)
User user = (User)
session.getAttribute("user");&
if (user == null) {&
user = new User();&
user.setId(1);&
session.setAttribute("user", user);&
return "index";&
访问sessionOut,然后再访问sessionIn,可以发现sessionIn的user可以访问到sessionOut设置的user&
需要注意的是,@SessionAttributes注解在处理器处理的时候,会根据session.getAttributes的返回内容,来处理一次,也就是,当return
(处理器是通过request.getSession(false),它不会创建session,如果session=null,直接return
null),就抛出异常HttpSessionRequiredException异常。&
而有时候,我们在session存放的对象,并非是必须存在的。解决这个问题有三个方法&
1.这个时候,我们就可以通过&
@ModelAttributes注解写在方法之前,并且这个方法没有@RequestMapping注解,那么这个方法会在之前处理的原理来解决。&
注意,当写在方法上面的@ModelAttribute("user")指定的名字和@SessionAttributes( {
})指定的名字中,刚好重合的时候,make方法在一个session中只会被调用一次。&
@SessionAttributes( { "user" })&
public class ControllerTest {&
private int x = 0;&
@ModelAttribute("user")&
public Object make(HttpSession session) {&
Object user = session.getAttribute("user");&
if (user == null) {&
user = new User();&
@RequestMapping(value = { "/", "home.do", "index",
"index.jsp",&
"index.html", "index.htm" })&
public String home(@ModelAttribute("user") User user, ModelMap
throws IOException {&
List&String& messages = new
ArrayList&String&();&
messages.add("你没有登录,请先登录!");&
messages.add("你输入的用户名不存在!");&
messages.add("无效的账号");&
model.put("messages", messages);&
return "application/index";&
上面的这种方法由于会依赖与HttpSession,这个时候这个类又重新依赖于servlet-api的架包了。不太好。&
我们可以换一种写法,使用ModelMap
model,这个样子就能把对jee架包的依赖消除了。&
@ModelAttribute("user")&
public Object make(ModelMap model) {&
Object user = model.get("user");&
if (user == null) {&
user = new User();&
@CookieValue注解&
@RequestMapping("/cookie")&
@ResponseBody&
public String cookie(@CookieValue("JSESSIONID") String sessionId)
return sessionId;&
@RequestHeader注解&
@RequestMapping("/head")&
@ResponseBody&
public String head(@RequestHeader("Accept-Encoding") String head)
还有一种方式就是利用&
WebBindingInitializer的功能,实现一个WebBindingInitializer,并且这个东西其实什么也不做,只是生成session的attributes。如&
package com.cgodo.daowole.web.&
org.springframework.web.bind.WebDataB&
org.springframework.web.bind.support.WebBindingI&
org.springframework.web.context.request.ServletRequestAttributes;&
org.springframework.web.context.request.WebR&
public class ClinicBindingInitializer implements
WebBindingInitializer {&
public void initBinder(WebDataBinder arg0, WebRequest arg1)
//从session&
Object& o = arg1.getAttribute("code",
ServletRequestAttributes.SCOPE_SESSION);&
if( o == null) {&
//放入session的值&
arg1.setAttribute("code", new String(), 1);&
WebBindingInitializer&
通过InitBinder注解或者天加一个WebBindingInitializer.的实现类&
@InitBinder写在@Controller的类中的方法上面,这个方法可以接受3个参数,当然这三个参数是灵活的。你需要定义几个都可以&
@InitBinder&
public void initBinder(WebDataBinder binder)
SimpleDateFormat dateFormat = new
SimpleDateFormat("yyyy-MM-dd");&
dateFormat.setLenient(false);&
binder.registerCustomEditor(Date.class, new
CustomDateEditor(&
dateFormat, false));&
@RequestMapping("/bind")&
@ResponseBody&
public String bind(Date date) {&
return "test";&
如上,定义中,binder.registerCustomEditor(Date.class, new
CustomDateEditor(&
dateFormat,
false));指定了Date类型将由CustomDateEditor属性编辑器完成初始化工作。&
WebBindingInitializer实现类实现方式&
package com.cgodo.daowole.web.&
org.springframework.web.bind.WebDataB&
org.springframework.web.bind.support.WebBindingI&
org.springframework.web.context.request.WebR&
public class ClinicBindingInitializer implements
WebBindingInitializer {&
public void initBinder(WebDataBinder arg0, WebRequest arg1)
System.out.println();&
这个时候,就要重写AnnotationMethodHandlerAdapter
bean的定义了。&
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"&--&&
&!-- &property name="cacheSeconds"
&!-- &property
name="webBindingInitializer"&--&&
&!-- &bean
class="com.cgodo.daowole.web.bind.ClinicBindingInitializer"
&/property&--&&
&/bean&--&&
注解驱动开启后会注册DefaultAnnotationHandlerMapping,&
默认情况下它生成的默认配置包括了&
interceptors 拦截器&
defaultHandler 默认的hangler mapping&
order 详细查看spring的order属性,Spring
将上下文中可用的映射进行排序,然后选用第一个和请求匹配的处理器。
alwaysUseFullPath 如果这个属性被设成true,Spring 将会使用绝对路径在当前的servlet
context中寻找合适的处理器。 这个属性的默认值是false,在这种情况下,Spring会使用当前servlet
context中的相对路径。
例如,如果一个servlet在servlet-mapping中用的值是/testing*;q=0.5&&
firefox:&&
Accept:text/html,application/xhtml+xml,application/q=0.9,*/*;q=0.8&
spring完成内容协商(content
negotiation)的工作是由ContentNegotiatingViewResolver来完成的&
是由LocaleResolver完成的。&
DispatcherServlet会查找locale解析器。我们可以通过RequestContext.getLocale()方法获取本地化。&
LocaleResolver的实现有&
AcceptHeaderLocaleResolver&
CookieLocaleResolver&
SessionLocaleResolver&
&bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver"&&
& &property name="cookieName"
value="clientlanguage"/&&
& &property name="cookieMaxAge"
value="100000"&&
CookieLocaleResolver的属性&
cookieName,默认是classname + LOCALE,由于是&
CookieLocaleResolver
还有一个属性是defaultLocale。如果没有个它设置默认值,那么在调用它的determineDefaultLocale方法的时候,会有判断,如果是null,就从request.getLocale();获取。&
org.springframework.web.servlet.i18n.CookieLocaleResolver处理的,所以叫org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE&
cookieMaxAge cookie的最大时间 默认 Integer.MAX_INT&
cookiePath cookie有效路径。 默认/&
另外还提供了一个请求参数拦截器,会根据请求参数,来修改对应的本地化解析器的本地化信息&
LocaleChangeInterceptor&
id="localeChangeInterceptor"&
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"&&
&property name="paramName" value="siteLanguage"
&bean id="localeResolver"&
class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"&&
name="interceptors"&&
&ref bean="localeChangeInterceptor"
&/property&&
&mvc:annotation-driven
那么配置应该是&
&mvc:interceptors&&
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"&&
&property name="paramName" value="siteLanguage"
&/mvc:interceptors&&
&bean id="lo
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 spring mvc 注解注入 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信