spring mvc 请求 json数据的处理

目前项目中json数据这种格式因为其简单,便于解析的特点而广泛应用于前后端的交互中,而spring mvc也支持对json这种格式数据的转换和解析。

1. 那其中就是HttpMessageConverter这个接口提供了这个转化和解析的功能,当然了不同的接口实现类支持不同的数据类型的转化和解析功能。我们先看看这个接口的构造。

package org.springframework.http.converter;

import java.io.IOException;
import java.util.List;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;

public interface HttpMessageConverter<T> {
    boolean canRead(Class<?> var1, MediaType var2);//判断该转换器是否可以将请求信息转化为var1类型的对象,同时支持var2类型的MIME类型

    boolean canWrite(Class<?> var1, MediaType var2);//判断该转换器是否可以将var1类型的数据写入到输出流中,完成响应,同时支持var2类型的MIME类型

    List<MediaType> getSupportedMediaTypes();//该转换器支持的MIME媒体类型

    T read(Class<? extends T> var1, HttpInputMessage var2) throws IOException, HttpMessageNotReadableException;//将var2输入流中的信息转化为var1类型的数据

    void write(T var1, MediaType var2, HttpOutputMessage var3) throws IOException, HttpMessageNotWritableException;//将var1类型的数据写入到var3的输出流中,同时支持var2 MIME媒体类型

2. 我们再来看看HttpMessageConverter的运行原理

spring mvc 请求 json数据的处理

2.1 HttpInputMessage先将请求的信息转化为InputStream对象,然后HttpMessageConverter转化器再将InputStream对象转换成Java Bean

2.2 Spring MVC经过处理返回一个Java Bean,然后HttpMessageConverter转换器将其转换为输出信息,接着由HttpOutputMessage将响应的信息转化为OutputStream对象,最后输出响应信息。

spring mvc 请求 json数据的处理

上图中给出了主要的几个实现了HttpMessageConverter接口的类,他们提供了xml,json,string,form.....几种数据类型转化功能

3. SpringMVC默认用MappingJacksonHttpMessageConverter对json数据进行转换,需要加入jackson的包

spring mvc 请求 json数据的处理

4. 下面讲解如何配置MappingJacksonHttpMessageConverter,在项目的中spring-servlet.xml中按照以下配置即可

<bean id="stringConverter" class="org.springframework.http.converter.StringHttpMessageConverter">  
    <property name="supportedMediaTypes">  
        <list>  
            <value>text/plain;charset=UTF-8</value>  
        </list>  
    </property>  
</bean>  
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>  


<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
    <property name="messageConverters">  
        <list>  
            <ref bean="stringConverter" />  
            <ref bean="jsonConverter" />  
        </list>  
    </property>  
</bean>  

如果spring-servlet.xml已经配置了<mvc:annotation-driven>,这时候上面的配置已经不需要了,<mvc:annotation-driven>已经默认配置好了MappingJackson2HttpMessageConverter,我们推荐使用这种配置方式。

5. 我们也可以使用Alibaba的FastJsonHttpMessageConverter,下面讲解如何配置,同样是在spring-servlet.xml中配置

<!-- 使用fastjson 配置 ,支持转化的请求数据类型为三种 -->
<!-- mvc:annotation-driven 会自动注册RequestMappingHandlerMapping与
RequestMappingHandlerAdapter两个Bean,这是Spring MVC为@Controller分发请求所必需的 -->
<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=UTF-8</value>
                    <value>application/json</value>
                    <value>application/xml;charset=UTF-8</value>
                </list>
            </property>
            <property name="features">
                <list>
                    <!-- 默认的意思就是不配置这个属性 -->
                    <!-- 是否输出值为null的字段 ,默认是false-->
                    <value>WriteMapNullValue</value>
                    <value>WriteNullNumberAsZero</value>
                    <value>WriteNullListAsEmpty</value>
                    <value>WriteNullStringAsEmpty</value>
                    <value>WriteNullBooleanAsFalse</value>
                    <value>WriteDateUseDateFormat</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

spring mvc 请求 json数据的处理

这里推荐一篇文章,里面有详细介绍几种json技术的比较,包括性能和功能,点击打开链接

如果只是功能要求,没有性能要求,可以使用google的Gson,

如果有性能上面的要求可以使用Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean

6. @RequestBody和@ResponseBody的使用,当controller类上加上该类注解时,spring 首先会根据请求头或者响应头中的content-type类型选择相应类型的HttpMessageConverter的转换器(根据HttpMessageConverter实现类中的canRead或者canWrite方法确定是否匹配),如果找不到相应的转换器,则报错

  6.1 @RequestBody

       该注解用于读取Http请求的请求体的内容,通过spring mvc提供的或者自己配置的实现了HttpMessageConverter接口的数据类型转换器将读取的内容转换成json等格式,最后转换成Java Bean对象,绑定到controller的参数上。

6.2 @ResponseBody

      该注解用于将controller返回的Java Bean,通过相应的HttpMessageConverter转换器转换为指定格式的数据(json,xml),最后通过Response返回给客户端。