以下为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>
</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"><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以便于让用户更方便的实现自定义的实现类。

<mvc:annotation-driven>新增标签的更多相关文章

  1. spring3 jsp页面使用<form:form modelAttribute="xxxx" action="xxxx">报错,附连接数据库的spring MVC annotation 案例

    在写一个使用spring3 的form标签的例子时,一直报错,错误信息为:java.lang.IllegalStateException: Neither BindingResult nor plai ...

  2. HTML5新增标签及具体用法

    html5自从推广普及以来,迅速被各大浏览器支持.采用html5设计的网页逐渐成为网页设计的时尚.下面就温习下html5的新增标签. HTML 5 中的新特性包括了嵌入音频.视频和图形的功能,客户端数 ...

  3. HTML5的文档结构和新增标签

    一.HTML5 文档结构1.第一步:打开 开发工具,打开指定文件夹:2.第二步:保存 index.html 文件到磁盘中,.html 是网页后缀:3.第三步:开始编写 HTML5 的基本格式.< ...

  4. 关于spring 3.0.5的 <mvc:resources mapping="***" location="***">标签的使用

    spring mvc 的<mvc;resources mapping="***" location="***">标签是在spring3.0.4出现的 ...

  5. HTML5新增标签的汇总与详解

    趁着一点闲暇时间,把HTML5的新增标签整理了一下,用了表格的形式展现,分别归纳了各标签的用法及属性分析.这样方便各位以后在运用HTML5标记遇到疑惑时,直接上来对照看下就明了了,希望对大家有帮助哦. ...

  6. 自学HTML5第二节(标签篇---新增标签详解)

    HTML5新增标签: <article> 标签 规定独立的自包含内容.一篇文章应有其自身的意义,应该有可能独立于站点的其余部分对其进行分发. <article> 元素的潜在来源 ...

  7. html 5 新增标签及简介

    作为下一代Web技术的代表,HTML5概念在近些年尤其火热.据了解,HTML5受到垂青最直接的原因就是其跨平台性,除此之外,它不仅仅可以用于表示Web内容,还可能将Web带入一个广阔的生态平台. 下面 ...

  8. HTML5学习总结——HTML5入门与新增标签

    一.HTML5概要 1.1.为什么需要HTML5 概念: HTML5 是继 HTML4.01, XHTML 1.0 和 DOM 2 HTML 后的又一个重要版本, 旨在消除富 Internet 程序( ...

  9. 盒子模型,定位技术,负边距,html5 新增标签

    盒子模型 /*[margin 外边距] margin属性最多四个 1.只写一个值,四个方向的margin均为这个值 2.写两个值:上,右两个方向,下默认=上,右 默认=左 3.写三个值:上.右.下三个 ...

  10. 第十课html5 新增标签及属性 html5学习5

    一.常用新增标签 1.header:定义页面的页眉头部 2.nav:定义导航栏 3.footer:定义页面底部,页脚 4.article:定义文章 5.section:定义区域 6.aside:定义侧 ...

随机推荐

  1. 自动填写IE的网页的输入框的内容

    procedure TForm1.PutData; var ShellWindow: IShellWindows; nCount: integer; spDisp: IDispatch; i,j,X: ...

  2. 12.MySQL必知必会之分组数据

    本文将介绍如何分组数据,以便能汇总表内容的子集,这涉及两个新SELECT语句子句,分别是 GROUP BY 子句和HAVING子句. 1.1 创建分组 分组是在SELECT语句的GROUP BY子句中 ...

  3. C# 使用 SqlBulkCopy 类批量复制数据到数据库

    最近公司需要优化导入的问题,由于之前使用的方式是生成 Insert 语句插入数据库,数据量小的时候还行,但是随着发展数据量渐渐大了,之前的方法性能就跟不上了,于是发现了 SqlBulkCopy 这个类 ...

  4. qqwry.dat输出乱码问题及maven打包后资源文件大小不一致的问题

    使用qqwry.dat进行IP地理位置查询时,遇到一个问题即在本地测试时查询纯真库时正常,没有任何问题,但是打包传到服务器上便出现了乱码问题. 1.首先排除服务器的字符集编码的影响 使用如下命令验证了 ...

  5. ABP官方文档翻译 1.2 N层架构

    N层架构 介绍 ABP架构 其他(通用) 领域层 应用层 基础设施层 网络和展现层 其他 总结 介绍 应用程序代码库的分层架构是被广泛认可的可以减少程序复杂度.提高代码复用率的技术.为了实现分层架构, ...

  6. php面向对象类中常用的魔术方法

    php面向对象类中常用的魔术方法   1.__construct():构造方法,当类被实例化new $class时被自动调用的方法,在类的继承中可以继承与覆盖该方法,例: //__construct( ...

  7. GridView自定义自增长的 序号 列

    如图所示,添加一个普通列(非模板列),将其显示文本为    序号 在GridView的RowDataBound事件中作如下处理 后台.CS 代码:

  8. python---自动群发邮件

    生活中我们经常发送邮件,那么我们能不能用Python写一个自动发送邮件的功能呢?答案是肯定的!!! 开始实现功能之前我们需要开启我们邮箱的 IMAP/SMTP功能,我们先了解一下什么是IMAP/SMT ...

  9. 通过paramiko模块在远程主机上执行命令

    安装paramiko模块 /usr/local/python36/bin/pip3 install paramiko 1.获取cpu使用率 #!/usr/bin/python #coding=utf8 ...

  10. 20144303 《Java程序设计》第七周学习总结

    20144303 <Java程序设计>第七周学习总结 教材学习内容总结 第十二章 Lambda Lambda表达式中this的参考对象以及toString()的接受者,是来自Lambda的 ...