- 浏览: 285932 次
- 性别:
- 来自: 上海
最新评论
-
javatozhang:
风间苍月 写道wddgfzs 写道使用JSR-303 Vali ...
Spring MVC 学习笔记 十 使用jsr 303进行校验 -
Fron:
...
Spring MVC 学习笔记 五 controller与requestmapping -
dwangel:
freemailfjgh 写道请问怎么才能获取dispatch ...
ContextLoaderListener与DispatcherServlet所加载的applicationContext的区别 -
di1984HIT:
学习了~~
Spring MVC 学习笔记 八 文件上传 -
di1984HIT:
学习了~~
Spring MVC 学习笔记 九 json格式的输入和输出
1:mvc annotation-driven 新增标签
以下为spring mvc 3.1中annotation-driven所支持的全部配置。
<mvc:annotation-driven message-codes-resolver ="bean ref" validator="" conversion-service=""> <mvc:return-value-handlers> <bean></bean> </mvc:return-value-handlers> <mvc:argument-resolvers> </mvc:argument-resolvers> <mvc:message-converters> </mvc:message-converters>[/color] </mvc:annotation-driven>
其中3.1新增部分如下
return-value-handlers
允许注册实现了HandlerMethodReturnValueHandler接口的bean,来对handler method的特定的返回类型做处理。
HandlerMethodReturnValueHandler接口中定义了两个方法
supportsReturnType 方法用来确定此实现类是否支持对应返回类型。
handleReturnValue 则用来处理具体的返回类型。
例如以下的handlerMethod
@RequestMapping("/testReturnHandlers") public User testHandlerReturnMethod(){ User u = new User(); u.setUserName("test"); return u; }
所返回的类型为一个pojo,正常情况下spring mvc无法解析,将转由DefaultRequestToViewNameTranslator 解析出一个缺省的view name,转到 testReturnHandlers.jsp,
我们增加以下配置
<mvc:annotation-driven validator="validator"> [color=red] <mvc:return-value-handlers> <bean class="net.zhepu.web.handlers.returnHandler.UserHandlers"></bean> </mvc:return-value-handlers>[/color] </mvc:annotation-driven>
及如下实现类
public class UserHandlers implements HandlerMethodReturnValueHandler { Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public boolean supportsReturnType(MethodParameter returnType) { Class<?> type = returnType.getParameterType(); if(User.class.equals(type)) { return true; } return false; } @Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { logger.info("handler for return type users "); mavContainer.setViewName("helloworld"); } }
此时再访问 http://localhost:8080/springmvc/testReturnHandlers ,将交由 UserHandlers来处理返回类型为User的返回值。
argument-resolvers
允许注册实现了WebArgumentResolver接口的bean,来对handlerMethod中的用户自定义的参数或annotation进行解析
例如
<mvc:annotation-driven validator="validator"> <mvc:argument-resolvers> <bean class="net.zhepu.web.handlers.argumentHandler.MyCustomerWebArgumentHandler" /> </mvc:argument-resolvers> </mvc:annotation-driven>
对应java代码如下
public class MyCustomerWebArgumentHandler implements WebArgumentResolver { @Override public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception { if (methodParameter.getParameterType().equals(MyArgument.class)) { MyArgument argu = new MyArgument(); argu.setArgumentName("winzip"); argu.setArgumentValue("123456"); return argu; } return UNRESOLVED; } }
这里我们定义了一个 customer webArgumentHandler,当handler method中参数类型为 MyArgument时生成对参数的类型绑定操作。
注意新注册的webArgumentHandler的优先级最低,即如果系统缺省注册的ArgumentHandler已经可以解析对应的参数类型时,就不会再调用到新注册的customer ArgumentHandler了。
message-converters
允许注册实现了HttpMessageConverter接口的bean,来对requestbody 或responsebody中的数据进行解析
例如
假设我们使用 text/plain格式发送一串字符串来表示User对象,各个属性值使用”|”来分隔。例如 winzip|123456|13818888888,期望转为user对象,各属性内容为user.username = winzip,user.password=123456;user.mobileNO = 13818888888
以下代码中supports表示此httpmessageConverter实现类针对 User类进行解析。
构造函数中调用 super(new MediaType("text", "plain"));以表示支持 text/plain格式的输入。
public class MyCustomerMessageConverter extends AbstractHttpMessageConverter<Object> { @Override protected boolean supports(Class<?> clazz) { if (clazz.equals(User.class)) { return true; } return false; } public MyCustomerMessageConverter() { super(new MediaType("text", "plain")); } @Override protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { Charset charset; MediaType contentType = inputMessage.getHeaders().getContentType(); if (contentType != null && contentType.getCharSet() != null) { charset = contentType.getCharSet(); } else { charset = Charset.forName("UTF-8"); } String input = FileCopyUtils.copyToString(new InputStreamReader( inputMessage.getBody(), charset)); logger.info(input); String[] s = input.split("\\|"); User u = new User(); u.setUserName(s[0]); u.setPassword(s[1]); u.setMobileNO(s[2]); return u; } @Override protected void writeInternal(Object t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { }
修改servlet context xml配置文件,增加message-converters的相应配置如下。
<mvc:message-converters> <bean class="net.zhepu.web.handlers.messageConverterHandler.MyCustomerMessageConverter"></bean> </mvc:message-converters>
message-codes-resolver
先看看spring mvc中对于messageCodeResolver的用法。
spring mvc中使用DefaultMessageCodesResolver作为缺省的MessageCodesResolver的实现类,其作用是对valid errors中的errorcode进行解析。其解析方式如下
当解析error global object注册的errorcode时,errorcode的查找顺序为
1:errorcode.validationobjectname
2:errorcode
例如
以下声明中
public String helloWorld2(@ModelAttribute("user") User u, BindingResult result)
当使用 result.reject("testFlag");来注册一个globat error object时,spring mvc将在messageSource中先查找 testFlag.user这个errorcode,当找不到时再查找testFlag这个errorcode。
当解析fields error时,将按以下顺序生成error code
1.: code + "." + object name + "." + field
2.: code + "." + field
3.: code + "." + field type
4.: code
还是以上面的代码为例,当使用 result.rejectValue("userName", "testFlag");来注册一个针对user.UserName属性的错误描述时,errors对象中将生成以下的error code list,
1.: testFlag.user.userName
2.: testFlag.userName
3.: testFlag.java.lang.String
4.: testFlag
而mvc:annotation-driven新增的属性message-codes-resolver则提供了注册自定义的MessageCodesResolver的手段。
例如上面想要在所有的error code前增加前缀validation.的话,可以这么来做
<mvc:annotation-driven validator="validator" message-codes-resolver="messageCodeResolver"> </mvc:annotation-driven>
新增messageCodeResolver bean定义如下
<bean id="messageCodeResolver" class="org.springframework.validation.DefaultMessageCodesResolver"> <property name="prefix" value="validation."></property> </bean>
此时,所有的errorcode都会生成缺省前缀 validation.
例如前面的 result.reject("testFlag"); 生成的error code list就变为了
validation.testFlag.user 和 validation.testFlag了。
2: @RequestMapping 新增参数Consumes 和Produces
前面介绍过@RequestMapping的参数中有一个header的参数,来指定handler method能接受的http request 请求的header内容。
而consumes和produces则更进一步,直接指定所能接受或产生的request请求的content type。
例如
@RequestMapping(value="/testMsgConverter",consumes="text/plain",produces="application/json")
表示handlermethod接受的请求的header中的 Content-Type为text/plain;
Accept为application/json
3: URI Template 新增功能
这部分的例子直接照抄Spring 3.1 M2: Spring MVC Enhancements中的示例
1: @PathVariable 声明的参数可自动加入到model中。
例如
@RequestMapping("/develop/apps/edit/{slug}") public String editForm(@PathVariable String slug, Model model) { model.addAttribute("slug", slug); // ... }
现在可以写为
@RequestMapping("/develop/apps/edit/{slug}") public String editForm(@PathVariable String slug, Model model) { // model contains "slug" variable }
2:handler method中的redirect string可支持url template了
例如
@RequestMapping( value="/groups/{group}/events/{year}/{month}/{slug}/rooms", method=RequestMethod.POST) public String createRoom( @PathVariable String group, @PathVariable Integer year, @PathVariable Integer month, @PathVariable String slug) { // ... return "redirect:/groups/" + group + "/events/" + year + "/" + month + "/" + slug; }
现在可写为
@RequestMapping( value="/groups/{group}/events/{year}/{month}/{slug}/rooms", method=RequestMethod.POST) public String createRoom( @PathVariable String group, @PathVariable Integer year, @PathVariable Integer month, @PathVariable String slug) { // ... return "redirect:/groups/{group}/events/{year}/{month}/{slug}"; }
3:url template中可支持databinding 了
例如
@RequestMapping("/people/{firstName}/{lastName}/SSN") public String find(Person person, @PathVariable String firstName, @PathVariable String lastName) { person.setFirstName(firstName); person.setLastName(lastName); // ... }
现在可以写成
@RequestMapping("/people/{firstName}/{lastName}/SSN") public String search(Person person) { // person.getFirstName() and person.getLastName() are populated // ... }
4: Validation For @RequestBody
@RequestBody现在直接支持@valid标注了,如果validation失败,将抛出
RequestBodyNotValidException。
具体处理逻辑可见 spring 中的RequestResponseBodyMethodProcessor中的以下代码。
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { Object arg = readWithMessageConverters(webRequest, parameter, parameter.getParameterType()); if (shouldValidate(parameter, arg)) { String argName = Conventions.getVariableNameForParameter(parameter); WebDataBinder binder = binderFactory.createBinder(webRequest, arg, argName); binder.validate(); Errors errors = binder.getBindingResult(); if (errors.hasErrors()) { throw new RequestBodyNotValidException(errors); } } return arg; }
5:annotation-driven缺省注册类的改变
Spring 3.0.x中使用了annotation-driven后,缺省使用DefaultAnnotationHandlerMapping 来注册handler method和request的mapping关系。
AnnotationMethodHandlerAdapter来在实际调用handlermethod前对其参数进行处理。
并在dispatcherServlet中,当用户未注册自定义的ExceptionResolver时,注册AnnotationMethodHandlerExceptionResolver来对使用@ExceptionHandler标注的异常处理函数进行解析处理(这也导致当用户注册了自定义的exeptionResolver时将可能导致无法处理@ExceptionHandler)。
在spring mvc 3.1中,对应变更为
DefaultAnnotationHandlerMapping -> RequestMappingHandlerMapping
AnnotationMethodHandlerAdapter -> RequestMappingHandlerAdapter
AnnotationMethodHandlerExceptionResolver -> ExceptionHandlerExceptionResolver
以上都在使用了annotation-driven后自动注册。
而且对应分别提供了AbstractHandlerMethodMapping , AbstractHandlerMethodAdapter和 AbstractHandlerMethodExceptionResolver以便于让用户更方便的实现自定义的实现类。
评论
10 楼
云端月影
2015-05-22
9 楼
sunhao_java
2015-02-04
8 楼
太阳神喻
2013-08-29
不顶不行啊
7 楼
finallygo
2013-06-18
Content-Type 不是response中的么?
6 楼
saintsaya
2013-01-17
好郁闷啊,看到第二个参数的楼主给解释了
5 楼
saintsaya
2013-01-17
你妹儿的试了第一个就给我整蒙了,写了一个类实现HandlerMethodReturnValueHandler接口然后在那两个方法里面写了两句话测试了一下,发各种请求死活都走不到我写的这两个方法,后来各种debug代码才知道这个returnHandler是有优先级的,我一直请求的方法返回值都是规规矩矩的ModelAndView,Map,String这几种,实际上spring mvc是先匹配他默认的一堆ModelAndView,Model,Map什么的Handler,最后才匹配自己写的这个,这不坑爹么,把自己写的放在最顶层设计多好,要不怎么去覆盖默认的啊,写在这里,以后有人犯了跟我一样的毛病就知道怎么回事儿了,写这个是用来解析spring mvc无法解析的返回值的,能解析的也无法用不过自己写的方法来覆盖它。
4 楼
dxqrr
2012-09-16
3 楼
lingjiangzhou0923
2012-06-03
2 楼
lingjiangzhou0923
2012-06-03
1 楼
hongyang070
2011-12-15
发表评论
-
ContextLoaderListener与DispatcherServlet所加载的applicationContext的区别
2011-06-27 23:27 14673spring通过在web.xml 中配置ContextLo ... -
Spring MVC 学习笔记 十四 对locale和theme的支持
2011-06-10 22:31 14435Locale Spring MVC缺省使用AcceptHead ... -
Spring MVC 学习笔记 十三 xml格式输入输出
2011-06-10 22:31 21359Xml格式输入 Spring mvc ... -
Spring MVC 学习笔记 十二 PDF/Excel格式输出
2011-06-07 21:24 10377Spring mvc 中对于输出格式为pdf和xsl的view ... -
Spring MVC 学习笔记 十一 data binding
2011-06-07 21:23 16536Servlet中的输入参数为都是string类型,而sprin ... -
Spring MVC 学习笔记 十 使用jsr 303进行校验
2011-06-02 21:05 20178Spring MVC在使用了<mvc:annotatio ... -
Spring MVC 学习笔记 九 json格式的输入和输出
2011-06-01 20:01 33770Spring mvc处理json需要使用jackson的类库, ... -
Spring MVC 学习笔记 八 文件上传
2011-06-01 19:59 4005Spring mvc使用jakarta的commons fil ... -
Spring MVC 学习笔记 七 controller中其他可用的annotation
2011-05-31 22:25 8686@InitBinder 在controller中注册一个c ... -
Spring MVC 学习笔记 六 Handler Method的可用参数
2011-05-31 22:24 12168使用@requesMapping标注的处理函数包括的可选 ... -
Spring MVC 学习笔记 五 controller与requestmapping
2011-05-29 22:04 36534使用@controller定义controllersSprin ... -
Spring MVC 学习笔记 四 Viewresol和View
2011-05-29 20:34 10521Spring MVC使用ViewResolver来根据c ... -
Spring MVC 学习笔记 三 handlerMapping和handlerAdapter
2011-05-27 23:30 36069HandlerMapping Spring mvc 使用Han ... -
Spring MVC 学习笔记 二 spring mvc Schema-based configuration
2011-05-25 22:32 8066Spring mvc 目前支持5个tag,分别是 mvc:an ... -
Spring MVC 学习笔记 一 创建项目
2011-05-25 00:11 80411:新建maven 工程 运行以下maven命令,建立一个je ...
相关推荐
spring mvc学习笔记spring mvc学习笔记spring mvc学习笔记spring mvc学习笔记spring mvc学习笔记
传智播客 Spring MVC 学习笔记
spring 3.1 mvc sample Spring 3.1的最新例子
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring MVC4是当前zuixin的版本,在众多特性上有了进一步的提升。, 在精通Spring...
spring mvc的学习笔记,主要讲解了基于xml的配置,和如何增加spring mvc拦截器,如何返回json报文
Spring 3.1 jar包Spring 3.1 jar包Spring 3.1 jar包Spring 3.1 jar包Spring 3.1 jar包
spring MVC 3.1+spring security3.1+mybaits+ 注解 实现安全机制。jar包没有上传。自己补充
spring mvc 基础笔记 源代码. 下载后倒入到eclipse当中。 请重新倒入Tomcat安装目录lib文件夹下的servlet-api.jar. 如果是jQuery.js文件有红色叉表示错误的话请无视。
Spring MVC是Spring框架中用于Web应用快速开发的一个模块,其中的MVC是Model-View-Controller的缩写。作为当今业界最主流的Web开发框架,Spring MVC已经成为当前最热门的开发技能,同时也广泛用于桌面开发领域。 ...
Spring3 MVC 学习笔记 入门 Spring3 MVC 学习笔记 入门
spring mvc学习笔记,包括学习遇到的问题和解决方法。
通俗移动的Spring MVC入门书籍。请尊重版权,禁止用于商业目的。
Spring MVC是Spring框架中用于Web应用快速开发的一个模块,其中的MVC是Model-View-Controller的缩写。作为当今业界最主流的Web开发框架,Spring MVC已经成为当前最热门的开发技能,同时也广泛用于桌面开发领域。 ...
以下这个学习案例是我最近学习Spring MVC时跟从一本 书上的示例,原文中的示例代码有一些小错误,不过我 在调试的过程中已经给予了修正,如还有其它错误,还 请各位批评指正。 对于现有较成熟的Model-View-...
Spring.MVC-A.Tutorial-Spring.MVC学习指南 高清可复制版PDF
Spring MVC 学习记录总结Spring MVC 是目前主流的实现MVC设计模式的框架,是Spring 框架的一个分支产品,以 Spring IoC 容器
演示spring3.1 mvc一个入门的例子