博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用spring MVC构建RESTful Web Services(二):消息转换
阅读量:6689 次
发布时间:2019-06-25

本文共 4966 字,大约阅读时间需要 16 分钟。

hot3.png

在前一节说到,如果在控制器中使用@ResponseBody或@RequestBody,spring MVC就会自动帮我们做“java对象<--->对应格式数据”的转换,用到的就是message converter。

消息转换的最上层是HttpMessageConverter,这是一个接口,它定义了消息转换实现类需要提供的方法:

232446_G2WJ_112325.png

根据方法名我们可以猜测其功能,canRead确定是否可以将数据转换为java对象,read则负责将数据转换为java对象;反之,canWrite确定是否可以将java对象转换为指定格式数据,write负责把java对象转换为对应格式的数据。这里有一个很重要的概念,就是MediaType,可以看到,messageConverter在做canWrite和canRead判断时,就是根据java对象类型和MediaType.

MediaType:互联网媒体类型,一般就是我们所说的 MIME 类型,用来确定请求的内容类型或响应的内容类型。

注:Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 如果您的请求中含有 Accept:“*/*”,则可以匹配功能处理方法上的如“text/html”、“text/*”,“application/xml”等。

    媒体类型格式:type/subtype(;parameter)?


        type 主类型,任意的字符串,如 text,如果是*号代表所有;

        subtype 子类型,任意的字符串,如 html,如果是*号代表所有;

        parameter 可选,一些参数,如 Accept 请求头的 q 参数, Content-Type 的 charset 参数。

    详见 http://tools.ietf.org/html/rfc2616#section-3.7

常见媒体类型:

    text/html : HTML 格式

    text/plain :纯文本格式
    text/xml :XML 格式
    image/gif :gif 图片格式 image/jpeg :jpg 图片格式 image/png:png 图片格式   
    application/x-www-form-urlencoded : <form encType=””>中默认的 encType,form 表单数据被编码为         key/value 格式发 送到服务器(表单默认的提交数据的格式)。

    multipart/form-data : 当你需要在表单中进行文件上传时,就需要使用该格式;
    application/xhtml+xml :XHTML 格式

    application/atom+xml :Atom XML 聚合格式

    application/pdf :pdf 格式

    application/octet-stream : 二进制流数据(如常见的文件下载)。
    application/xml: XML 数据格式
    application/json : JSON 数据格式

    可见,每个messageConverter会处理一个或几个MediaType到java对象的读、写转换。通过下面的类结构图我们就会一目了然。

234741_gORw_112325.png

下面说说我们经常用到的messageConverter:

1.StringHttpMessageConverter

它默认处理MediaType是text/plan和*/*(所有类型)的数据到java的转换。即String的转换处理,请注意,它默认的字符编码是ISO-8859-1,为避免乱码,我们改成UTF-8。spring bean的声明方式如下,也可以直接new 对象使用。因为它的构造函数中有默认编码参数,所以可以像下面这样设置。

    
 

我们还可以调整它支持的MediaType,比如只支持text/plan:

    
        
            
text/plan;charset=utf-8
        
    

2.FormHttpMessageConverter

我们程序里经常会有“http:sample.com/url?param1=value1&param2=value2……”这种URL的情况,看到好多朋友if、else的拼,我都深表同情。如果用FormHttpMessageConverter该多方便啊,它只处理java类型是MultiValueMap的数据,这是spring自定义的类型,扩展自Map.

    MultiValueMap
 formData = new LinkedMultiValueMap
();    formData.add("media", resource);    formData.add("filename", filename);    formData.add("filelength", Long.toString(resource.contentLength()));    formData.add("filelength", Long.toString(17408));        HttpHeaders headers = new HttpHeaders();    headers.setContentType(MediaType.MULTIPART_FORM_DATA);    HttpEntity
> requestEntity = new HttpEntity
>(formData, headers);        AccessTokenModel tokenModel = getRestTemplate().postForObject(MULTIPART_UPLOAD_URL,requestEntity, AccessTokenModel.class);

上面这个例子用到了spring提供的RestTemplate来请求URL,我们请求是POST形式,RestTemplate的方法名开头表示了URL请求类型,postForObject表示我们请求方式是POST,且我们要求返回java对象数据,这里返回的是AccessTokenModel对象,可以看到,它里面封装了很多细节,我们只需要准备数据,然后通过它调用即可,数据转换全部交由它来完成。

在调用postForObject方法时,我们传了一个参数类型是HttpEntity的对象,它用来指示RestTemplate我们的数据和数据格式,这里是MediaType.MULTIPART_FORM_DATA,即multipart/form-data,如果不需要上传文件,可以指定MediaType是application/x-www-form-urlencoded,即form表单数据。这两种MediaType都由FormHttpMessageConverter来处理。
spring bean的声明方式如下,

3.Jaxb2RootElementHttpMessageConverter

这个是用来处理JAXB的XML与java对象间的数据转换的。之前我介绍过JAXB,它是SOAP版的一部分,虽然SOAP已经不受宠,但JAXB真心好用。想想,只需要在类上加些注解,就可以自定义生成的格式信息,这是何等的方便,所以,转xml的工作就交给它了。而且它还有一个优势,随后会说到。

4.MappingJackson2HttpMessageConverter

这个是java转JSON的消息转换类。可能有人会问,java转JSON的工具千千万,为什么要选它呢?

原因一、好用,支持java、JSON转换;支持直接操纵JSON流对象;支持一些低级操作,如果效率优先,可以使用它们。单从这三点,不比其他工具差

原因二、spring MVC已经内置支持,只需简单设置,不需要自己再去写一套来适配了

原因三、上面说了,JAXB有一个优势,使用广泛。它的一些注解已经成为标准。而jackson适配了JAXB的注解,提供了JaxbAnnotationIntrospector这个模块,一个注解,两处使用,何其方便。再者现在主流格式就是XML和JSON,有这两个就够了。

下面看用JAXB注解定义的java对象:

@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "", propOrder = {        "name",        "pwd","age","birthday","inner"})@XmlRootElement(name = "ConverterVO")public class ConverterVO {    private String name;    private String pwd;    private Integer age;    @XmlElement(name = "birthday")    @XmlJavaTypeAdapter(DateAdapter.class)    private Date birthday;    private InnerConverterVO inner;    //gettter and setter……   }public class InnerConverterVO{    private String name;    private Integer innerId;    //gettter and setter……   }

生成的xml数据如下:

xiaowang
123456
15
1996-10-15 00:50:17
1111
innerConvertVO

生成的JSON数据如下:

{"name":"xiaowang","pwd":"123456","age":15,"birthday":"1996-10-15 00:46:34","inner":{"name":"innerConvertVO","innerId":1111}}

现在,我们的spring MVC的配置文件就变成了这样:

        
            
            
            
                
                        
                
                        
        
    
        
            
        
            
            

ps:关于MediaType一块使用了开涛整理的信息。

转载于:https://my.oschina.net/wuxianAbs/blog/266689

你可能感兴趣的文章
单例模式的有缺点
查看>>
perl基础1
查看>>
chrome浏览器如何通过js判断是否安装了某扩展?
查看>>
奔驰的罪恶
查看>>
redhat 6.5 mysql主从同步
查看>>
js 变量、作用域和内存问题
查看>>
Android actionBar 修改背景色
查看>>
项目质量管理,人力资源管理作业
查看>>
Android中HttpClient网络请求
查看>>
我的友情链接
查看>>
Backbone
查看>>
asterisk架构
查看>>
python sys模块
查看>>
PHP基础(三)函数
查看>>
我的友情链接
查看>>
linux shell脚本的使用
查看>>
c语言使用DES_ncbc_encrypt以及段错误 (核心已转储) 解决
查看>>
mockplus软件审阅功能界面图
查看>>
马哥笔记第二天
查看>>
009 牌视图实现
查看>>