深入解析 Spring MVC的配置文件

1.关于mvc 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>

说明:

      return-value-handlers                 ---     请求方法的返回值(出参)处理        -----   HandlerMethodReturnValueHandler

      argument-resolvers                     ---     请求方法的入参处理             -----   HandlerMethodArgumentResolver  或 WebArgumentResolver

      message-converters                   ---     消息转换处理                          -----   HttpMessageConverter


2.自定义各个属性演示

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>
</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的返回值

2、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>

3、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了

@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 

URI Template 新增功能 
@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
}

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}";
}

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
    // ...
}

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;
}



3.配置演示   mvc:annotation-driven默认都干了点神马???

      里面的默认值,都可以通过实现接口或继承的方式,自定义替换

<!-- 配置路径扩展名映射的媒体类型 -->  
    <bean name="pathExtensionContentNegotiationStrategy"  
        class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">  
        <constructor-arg>  
            <props>  
                <!-- if romePresent -->  
                <prop key="atom">application/atom+xml</prop>  
                <prop key="rss">application/rss+xml</prop>  
                <!-- endif -->  
                <!-- if jackson2Present || jacksonPresent -->  
                <prop key="json">application/json</prop>  
                <!-- endif -->  
                <!-- if jaxb2Present -->  
                <prop key="xml">application/xml</prop>  
                <!-- endif -->  
            </props>  
        </constructor-arg>  
    </bean>  
  
    <!-- 配置映射媒体类型的策略 -->  
    <bean name="mvcContentNegotiationManager"  
        class="org.springframework.web.accept.ContentNegotiationManager">  
        <constructor-arg>  
            <list>  
                <ref bean="pathExtensionContentNegotiationStrategy" />  
            </list>  
        </constructor-arg>  
    </bean>  
  
    <!-- 配置方法级别的@RequestMapping处理器 -->  
    <bean name="requestMappingHandlerMapping"  
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">  
        <property name="order" value="0" />  
        <property name="contentNegotiationManager" ref="mvcContentNegotiationManager" />  
    </bean>  
  
    <!-- 配置数据转换服务,默认使用格式化数据转换服务,可以对日期和数字进行格式化 -->  
    <bean name="conversionService"  
        class="org.springframework.format.support.DefaultFormattingConversionService">  
        <constructor-arg index="0">  
            <null></null>  
        </constructor-arg>  
        <constructor-arg index="1">  
            <value>true</value>  
        </constructor-arg>  
    </bean>  
  
    <bean name="validator"  
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"></bean>  
  
    <!-- 配置数据绑定,通过转换服务实现绑定,如果包含jsr303实现还将进行校验 -->  
    <bean name="webBindingInitializer"  
        class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">  
        <property name="conversionService" ref="conversionService" />  
        <!-- if jsr303Present -->  
        <property name="validator" ref="validator" />  
        <!-- endif -->  
    </bean>  
  
    <bean name="byteArrayHttpMessageConverter"  
        class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>  
    <bean name="stringHttpMessageConverter"  
        class="org.springframework.http.converter.StringHttpMessageConverter">  
        <property name="writeAcceptCharset" value="false" />  
    </bean>  
    <bean name="resourceHttpMessageConverter"  
        class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>  
    <bean name="sourceHttpMessageConverter"  
        class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>  
    <bean name="allEncompassingFormHttpMessageConverter"  
        class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter"></bean>  
    <bean name="atomFeedHttpMessageConverter"  
        class="org.springframework.http.converter.feed.AtomFeedHttpMessageConverter"></bean>  
    <bean name="rssChannelHttpMessageConverter"  
        class="org.springframework.http.converter.feed.RssChannelHttpMessageConverter"></bean>  
    <bean name="jaxb2RootElementHttpMessageConverter"  
        class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>  
    <bean name="mappingJackson2HttpMessageConverter"  
        class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>  
    <bean name="mappingJacksonHttpMessageConverter"  
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>  
  
    <!-- 配置@RequestBody,@ResponseBody注解可用的转换器 -->  
    <util:list id="messageConverters"  
        list-class="org.springframework.beans.factory.support.ManagedList.ManagedList">  
        <ref bean="byteArrayHttpMessageConverter" />  
        <ref bean="stringHttpMessageConverter" />  
        <ref bean="resourceHttpMessageConverter" />  
        <ref bean="sourceHttpMessageConverter" />  
        <ref bean="allEncompassingFormHttpMessageConverter" />  
        <!-- if romePresent -->  
        <ref bean="atomFeedHttpMessageConverter" />  
        <ref bean="rssChannelHttpMessageConverter" />  
        <!-- endif -->  
        <!-- if jaxb2Present -->  
        <ref bean="jaxb2RootElementHttpMessageConverter" />  
        <!-- endif -->  
        <!-- if jackson2Present -->  
        <ref bean="mappingJackson2HttpMessageConverter" />  
        <!-- endif -->  
        <!-- if jacksonPresent -->  
        <ref bean="mappingJacksonHttpMessageConverter" />  
        <!-- endif -->  
    </util:list>  
  
    <!-- 将任意类型的Controller适配为Handler -->  
    <bean name="requestMappingHandlerAdapter"  
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">  
        <property name="contentNegotiationManager" ref="mvcContentNegotiationManager" />  
        <property name="webBindingInitializer" ref="webBindingInitializer" />  
        <property name="messageConverters" ref="messageConverters" />  
    </bean>  
  
    <!-- 这个拦截器暴露转换器服务让spring:bind和spring:eval标签可用 -->  
    <bean name="csInterceptor"  
        class="org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor">  
        <constructor-arg index="0">  
            <ref bean="conversionService" />  
        </constructor-arg>  
    </bean>  
  
    <!-- 现在所有拦截器都必须设定响应的路径映射 -->  
    <bean name="mappedCsInterceptor"  
        class="org.springframework.web.servlet.handler.MappedInterceptor">  
        <constructor-arg index="0">  
            <null></null>  
        </constructor-arg>  
        <constructor-arg index="1">  
            <ref bean="csInterceptor" />  
        </constructor-arg>  
    </bean>  
  
    <!-- 使用@ExceptionHandler注解的方法来处理Exception,优先级为0(最高) -->  
    <bean name="exceptionHandlerExceptionResolver"  
        class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">  
        <property name="contentNegotiationManager" ref="mvcContentNegotiationManager" />  
        <property name="messageConverters" ref="messageConverters" />  
        <property name="order" value="0" />  
    </bean>  
  
    <!-- 如果抛出的Exception类带有@ResponseStatus注解,响应返回该注解的Http状态码,优先级为1 -->  
    <bean name="responseStatusExceptionResolver"  
        class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver">  
        <property name="order" value="1" />  
    </bean>  
  
    <!-- SpringMvc内部异常处理 -->  
    <bean name="defaultExceptionResolver"  
        class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver">  
        <property name="order" value="2" />  
    </bean>  


4.mvc:annotation-driven的日期处理

<mvc:annotation-driven />就是
A。注册了
一个RequestMappingHandlerMapping,
一个RequestMappingHandlerAdapter
和一个ExceptionHandlerExceptionResolver
(其中包括)支持使用注解标注在Controller方法的处理请求,例如@RequestMapping ,@ExceptionHandler等等

B。它还执行以下操作:
1. Spring 3 style type conversion through a ConversionService instance in addition to the JavaBeans PropertyEditors used for Data Binding.
2. Support for  formatting Number fields using the  @NumberFormat annotation through the ConversionService.
3. Support for  formatting Date, Calendar, Long, and Joda Time fields using the @DateTimeFormat annotation.
4. Support for  validating @Controller inputs with  @Valid, if a JSR-303 Provider is present on the classpath.
5. HttpMessageConverter support for  @RequestBody method parameters and  @ResponseBody method return values from @RequestMapping or @ExceptionHandler methods.

C。Details for B5
This is the complete list of HttpMessageConverters set up by  mvc:annotation-driven :
• ByteArrayHttpMessageConverter converts byte arrays.
• StringHttpMessageConverter converts strings.
• ResourceHttpMessageConverter converts to/from org.springframework.core.io.Resource for all media types.
• SourceHttpMessageConverter converts to/from a javax.xml.transform.Source.
• FormHttpMessageConverter converts form data to/from a  MultiValueMap<String,String>.
• Jaxb2RootElementHttpMessageConverter converts Java objects to/from XML — added if JAXB2 is present on the classpath.
• MappingJackson2HttpMessageConverter (or MappingJacksonHttpMessageConverter) converts to/from JSON — added if Jackson 2 (or Jackson) is present on the classpath.
• AtomFeedHttpMessageConverter converts Atom feeds — added if Rome is present on the classpath.
• RssChannelHttpMessageConverter converts RSS feeds — added if Rome is present on the classpath.


其实相信在大多数实际应用环境中使用mvc:annotation-driven是少数,因为一般都满足不了需求,但想快速搭配环境还是比较适合的.当使用java config,记得有文章介绍不推荐配置RequestMappingHandlerMapping和RequestMappingHandlerAdapter


如果不使用mvc:annotation-driven,日期又如何处理.  
        ---    使用@DateTime(patter="yyyy-MM-dd HH:mm:ss") ,在Controller方法参数或Vo属性中添加该注解,需要joda-time包
        ---    使用序列化和反序列化方式实现,自定义序列化和反序列化解析类,通过注解实现                 

@JsonSerialize(using = DateJsonSerializer.class)

@JsonDeserialize(using = DateJsonDeserializer.class)

private Date createTime;


spring mvc默认是支持yyyy-MM-dd格式的字符串转换为java的java.util.Date.包括spring mvc框架本身和spring mvc支持的jackson.
对于其它格式的日期的字符串与Java的Date对象相互转化,一样可分为两种情况:
A:一种普通请求,前台的日期字符串与后台的Java Date对象转化,此情况,应使用spring mvc本身的内置日期处理.
B:另一种将参数写进请求体里面,使用application/json这样的mediaType发请求,对于此情况,应使用Jackson的序列化和反序列化来处理.

一.第1种情况(不要忘了加joda-time包哦):
1.先使用@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")在Controller的方法参数或VO的属性使用.
2.如果不使用mvc:annotation-driven,那么使用数据绑定来处理@DateTimeFormat这样的注解.配置例子如下:

[html]  view plain  copy
 
  1. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />  
  2. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">  
  3.     <property name="webBindingInitializer">  
  4.         <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">  
  5.             <property name="conversionService" ref="conversionService" />  
  6.         </bean>  
  7.     </property>  
  8.     <property name="messageConverters">  
  9.         <list>  
  10.             <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/>  
  11.             <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">  
  12.                 <property name="supportedMediaTypes">  
  13.                     <list>  
  14.                         <value>application/json; charset=UTF-8</value>  
  15.                         <value>text/html; charset=UTF-8</value>  
  16.                     </list>  
  17.                 </property>  
  18.             </bean>  
  19.         </list>  
  20.     </property>  
  21. </bean>  
  22. <bean id="conversionService" class="org.springframework.format.support.DefaultFormattingConversionService"/>  
二.第2种情况:
1.继承定义序列化和反序列化类.例子:
[java]  view plain  copy
 
  1. public class DateJsonSerializer extends JsonSerializer<Date> {  
  2.     public static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  3.     @Override  
  4.     public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {  
  5.         jsonGenerator.writeString(format.format(date));  
  6.     }  
  7. }  
[java]  view plain  copy
 
  1. public class DateJsonDeserializer extends JsonDeserializer<Date> {  
  2.     public static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  3.     @Override  
  4.     public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {  
  5.         try {  
  6.             return format.parse(jsonParser.getText());  
  7.         } catch (ParseException e) {  
  8.             throw new RuntimeException(e);  
  9.         }  
  10.     }  
  11. }  
2.在VO使用@JsonSerialize(using = DateJsonSerializer.class)和@JsonDeserialize(using = DateJsonDeserializer.class)注解(属性或方法都可以,序列化标注在get方法,反序列化标注在set方法).

@JsonSerialize(using = DateJsonSerializer.class)

@JsonDeserialize(using = DateJsonDeserializer.class)

private Date createTime;



5.Spring MVC中配置,支持json和jsonp


场景:方便使用spring mvc生成json,并且兼容ie,chrome....

设计:手工指定RequestMappingHandlerMapping和RequestMappingHandlerAdapter,并给RequestMappingHandlerAdapter的messageConverters的注入属性值.不使用驱动注解(<mvc:annotation-driven />)自动配置的原因是:自动配置我没找到方法来修改response的Content-Type, 而自动配置默认的content-type是application/json;charset=UTF-8.这个contentType在谷歌浏览器很正常解析,而到了IE解析为弹出下载了,IE10,IE11一样不给面子!!!如果将contentType改为:text/html;charset=UTF-8.那IE和google浏览器都能正常解析了.


不用再去写<mvc:annotation-driven />,至于<mvc:annotation-driven />在背后做了什么,可看参考手册.注意spring版本哦,这两类从3.1才开始有的.


基于xml配置:

[html]  view plain  copy
 
  1. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />  
  2. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">  
  3.     <property name="messageConverters">  
  4.         <list>  
  5.             <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">  
  6.                 <property name="supportedMediaTypes">  
  7.                     <list>  
  8.                         <value>text/html;charset=UTF-8</value>  
  9.                         <value>application/json;charset=UTF-8</value>  
  10.                     </list>  
  11.                 </property>  
  12.             </bean>  
  13.         </list>  
  14.     </property>  
  15. </bean>  

基于Java-config方式会更加简单一点,先让你的mvc配置继承WebMvcConfigurerAdapter,再重写configureMessageConverters方法,加入jackson包,在controller使用@ResponseBody注解,OK!

如果要全局支持jsonp(支持jsonp的做法:可以在controller的方法返回String类型,接收一下callback,然后callback调用一下json结果就可以),可以再加一个StringHttpMessageConverter,不仅能解决中文乱码,还能把json里面的换行\r\n去掉.

[html]  view plain  copy
 
  1. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />  
  2. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">  
  3.     <property name="messageConverters">  
  4.         <list>  
  5.             <bean class="org.springframework.http.converter.StringHttpMessageConverter">  
  6.                 <property name="supportedMediaTypes">  
  7.                     <list>  
  8.                         <value>text/html; charset=UTF-8</value>  
  9.                         <value>application/json;charset=UTF-8</value>  
  10.                     </list>  
  11.                 </property>  
  12.             </bean>  
  13.             <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">  
  14.                 <property name="supportedMediaTypes">  
  15.                     <list>  
  16.                         <value>text/html; charset=UTF-8</value>  
  17.                         <value>application/json;charset=UTF-8</value>  
  18.                     </list>  
  19.                 </property>  
  20.             </bean>  
  21.         </list>  
  22.     </property>  
  23. </bean>  


你可能感兴趣的:(深入解析 Spring MVC的配置文件)