博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springboot传入json和文件_SpringBoot系列教程22-整合SpringMVC之HttpMessageConverters
阅读量:6375 次
发布时间:2019-06-23

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

SpringBoot系列教程22--整合SpringMVC之HttpMessageConverters

作者:一一哥

一.HttpMessageConverter简介

1.概述

现在我们进行web开发,一般都要设计成RESTful风格的API,通过json格式的数据进行交互。但是前端传入的 json 数据如何被解析成 Java 对象作为 API入参,后端返回结果又如何将 Java 对象解析成 json 格式数据返回给前端,在整个数据流转过程中,这是由谁来完成的呢?

其实这都是由HttpMessageConverter起到的作用!

2.HttpMessageConverter简介

org.springframework.http.converter.HttpMessageConverter 是SpringMVC中提供的一个策略接口,它是一个转换器类,负责转换HTTP请求和响应,可以把对象自动转换为JSON(使用Jackson库或Gson库)或XML(使用Jackson XML或者JAXB2),对字符串默认使用UTF-8编码处理,一般情况下采用默认配置就可以。

该接口说明如下:

Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.

简单说就是 HTTP request (请求)和response (响应)的转换器。该接口里有5个方法,接收到请求时判断是否能读(canRead),能读则读(read);返回结果时判断是否能写(canWrite),能写则写(write),以及获取支持的 MediaType(application/json之类)方法。

boolean canRead(Class
clazz, MediaType mediaType);boolean canWrite(Class
clazz, MediaType mediaType);List
getSupportedMediaTypes();T read(Class
clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;void write(T t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;

3.HttpMessageConverter转换原理

利用SpringMVC框架,可以使得我们在开发时,只要在代码中使用@RequestBody和@ResponseBody两个注解,就可以分别完成从请求报文到对象和从对象到响应报文的转换。而在源码内部,其实这种灵活的消息转换机制就是利用HttpMessageConverter来实现的。

实现过程参考下图:

4d8fa9046353effc29649b6271af27f3.png

SpringMVC在启动时会自动配置一些默认的HttpMessageConverter转换器,在 WebMvcConfigurationSupport 类中添加了缺省的MessageConverter,比如MappingJackson2HttpMessageConverter,StringHttpMessageConverter等。

protected final void addDefaultHttpMessageConverters(List
> messageConverters) { StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); stringConverter.setWriteAcceptCharset(false); messageConverters.add(new ByteArrayHttpMessageConverter()); messageConverters.add(stringConverter); messageConverters.add(new ResourceHttpMessageConverter()); messageConverters.add(new SourceHttpMessageConverter
()); messageConverters.add(new AllEncompassingFormHttpMessageConverter()); if (romePresent) { messageConverters.add(new AtomFeedHttpMessageConverter()); messageConverters.add(new RssChannelHttpMessageConverter()); } if (jackson2XmlPresent) { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.xml().applicationContext(this.applicationContext).build(); messageConverters.add(new MappingJackson2XmlHttpMessageConverter(objectMapper)); } else if (jaxb2Present) { messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().applicationContext(this.applicationContext).build(); messageConverters.add(new MappingJackson2HttpMessageConverter(objectMapper)); } else if (gsonPresent) { messageConverters.add(new GsonHttpMessageConverter()); } }

从源码中可以看到,SpringMVC中使用Jackson库或Gson库来转换json字符串,使用使用Jackson XML或者JAXB2来转换xml。

而如果我们没有配置自己的 MessageConverter,SpringMVC 启动时就会调用 addDefaultHttpMessageConverters方法。

5e9d322a97733c71388dd7008a537808.png

4.Spring Boot中自定义HttpMessageConverters实现思路

在Spring Boot中我们可以使用HttpMessageConverters添加HttpMessageConverter原生转换类或自定义转换类。

import org.springframework.boot.autoconfigure.web.HttpMessageConverters;import org.springframework.context.annotation.*;import org.springframework.http.converter.*;@Configurationpublic class MyConfiguration {    @Bean    public HttpMessageConverters customConverters() {        HttpMessageConverter
additional = ... HttpMessageConverter
another = ... return new HttpMessageConverters(additional, another); }}

从上面的代码示例中,我们看到可以把HttpMessageConverter添加到converters列表,通过这种方式覆盖默认的转换器列表(converters)。

5.自定义消息转换器的方式

我们可以自定义自己的消息转换器来满足特定的需求,一般自定义消息转换器有两种方式:

  • 1、使用spring或者第三方提供的现成的HttpMessageConverter;
  • 2、自己重写一个HttpMessageConverter。

二.Spring Boot中用FastJsonHttpMessageConverter替换默认转换器

1.创建SpringBoot项目

我们在之前的基础上,新建一个demo10,并将其改造成SpringBoot项目。

1ecbab9795660dace62eabea77f2350d.png

2.添加FastJson依赖

在SpringBoot项目中,当我们在控制器类或者其内部的方法上添加@RestController注解和@ResponseBody注解后,默认会使用jackson插件来返回json格式的数据,但是我们也可以利用fastjson为我们提供的FastJsonHttpMessageConverter来返回json格式的数据。

首先引入fastjson的依赖。

com.alibaba
fastjson
1.2.61

3.配置FastJsonHttpMessageConverter

我们可以通过实现WebMvcConfigurer接口,来配置FastJsonHttpMessageConverter,在Spring Boot2.0版本以后推荐使用这种方式来进行web配置,这样不会覆盖掉Spring Boot的一些默认配置.

我们创建如下的目录结构。

e4921bd1575dc31f65d2d59b21427f21.png
/** *实现WebMvcConfigurer接口来配置FastJsonHttpMessageConverter, *Spring Boot2.0版本以后推荐使用这种方式来进行web配置,这样不会覆盖掉Spring Boot的一些默认配置. */@Configurationpublic class CustomWebMvcConfigurer implements WebMvcConfigurer {    @Override    public void extendMessageConverters(List
> converters) { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); FastJsonConfig config = new FastJsonConfig(); config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect); converter.setFastJsonConfig(config); converter.setDefaultCharset(Charset.forName("UTF-8")); converters.add(converter); }}

3.1 fastJson中的SerializerFeature

在fastJson配置实体时,会调用setSerializerFeatures方法,可以配置多个过滤方式,常用的如下:

803180451062debb03ddfaf440f048e8.png

常用的SerializerFeature释义

QuoteFieldNames,//输出key时是否使用双引号,默认为true;UseSingleQuotes,//使用单引号而不是双引号,默认为false;WriteMapNullValue,//是否输出值为null的字段,默认为false; WriteEnumUsingToString,//Enum输出name()或者original,默认为false;UseISO8601DateFormat,//Date使用ISO8601格式输出,默认为false;WriteNullListAsEmpty,//List字段如果为null,输出为[],而非null;WriteNullStringAsEmpty,//字符类型字段如果为null,输出为"",而非null;      WriteNullNumberAsZero,//数值字段如果为null,输出为0,而非null;WriteNullBooleanAsFalse,//Boolean字段如果为null,输出为false,而非null;SkipTransientField,//如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true;SortField,//按字段名称排序后输出,默认为false;@DeprecatedWriteTabAsSpecial,//把t做转义输出,默认为false;PrettyFormat,//结果是否格式化,默认为false;WriteClassName,//序列化时写入类型信息,默认为false,反序列化是需用到;DisableCircularReferenceDetect,//消除对同一对象循环引用的问题,默认为false;WriteSlashAsSpecial,//对斜杠'/'进行转义;BrowserCompatible,//将中文都会序列化为uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false;WriteDateUseDateFormat,//全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd";JSON.toJSONString(obj,SerializerFeature.WriteDateUseDateFormat);DisableCheckSpecialChar,//一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性,默认为false.

4.创建对象实体

我们创建一个“com.yyg.boot.domain”包,在这里创建一个User实体类。

package com.yyg.boot.domain;import lombok.AllArgsConstructor;import lombok.Data;@Data@AllArgsConstructorpublic class User {    private String name;    private String address;}

5.创建Controller

我们创建“com.yyg.boot.web”包,在里面创建一个Controller类。

package com.yyg.boot.web;import com.yyg.boot.domain.User;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;import java.util.List;@RestControllerpublic class UserController {    @RequestMapping(value = "/get", method = RequestMethod.GET)    public Object getList() {        List
list = new ArrayList<>(); //测试字符串有null的情况 User u1 = new User("一一哥", null); list.add(u1); return list; }}

6.创建程序入口类

在项目根目录下创建启动类。

package com.yyg.boot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * 自定义HttpMessageConverter */@SpringBootApplicationpublic class ConvertApplication {    public static void main(String[] args) {        SpringApplication.run(ConvertApplication.class, args);    }}

整个项目结构:

f3c2fe9636effb8cab9bdba2a8f1d3a2.png

7.启动类进行测试

启动项目访问http://localhost:8080/users

因为我们CustomWebMvcConfigurer类的代码中没有配置WriteMapNullValue,所以如果返回结果中有null值则不显示,结果如下:

8237dd979467540e839ae970bffed485.png

接着我们可以在CustomWebMvcConfigurer中添加WriteMapNullValue,如下图:

a46c669d78297efe4ef66f80d6d06f61.png

然后重新启动项目并访问,从结果可以看出我们配置的消息转换器起作用。

cd3e06196034b69f1c55dc0da49b5ace.png

接着我们可以在CustomWebMvcConfigurer中添加WriteNullStringAsEmpty,如下图:

78ac9f8e52d725a4f3231c5abf6dfb4d.png

然后重新启动项目并访问,从结果可以看出我们配置的消息转换器又起了作用。

d43eef9ffe96aa72b6c9c597226a2a8d.png

转载地址:http://eavqa.baihongyu.com/

你可能感兴趣的文章
简单配置Oracle10g DataGuard物理备库
查看>>
网曝支付宝漏洞:手机丢了,支付宝也就完了
查看>>
4 在vCenter Server安装View Composer组件
查看>>
SFB 项目经验-24-为持久聊天室-查询或者增加成员
查看>>
Linux下配置Squid基础教程
查看>>
当Cacti遭遇大流量
查看>>
Outlook Anywhere 客户端配置详解
查看>>
来,测一下你的学习能力!
查看>>
《Windows Server 2008 R2系统管理实战》前言与内容提要
查看>>
轻巧的网络流量实时监控工具NTOPNG
查看>>
MySQL的log_bin和sql_log_bin 到底有什么区别?
查看>>
Access、Sql 获取当前插入的主键ID
查看>>
聚类算法之DBScan(Java实现)
查看>>
为什么要使用AOP?
查看>>
VC :模板类
查看>>
对C++中string类型的总结
查看>>
Oracle发布公共云Public Cloud
查看>>
表驱动
查看>>
eclipse高亮显示
查看>>
Shell 操作数据库
查看>>