SpringBoot中使用Fastjson/Jackson对JSON序列化格式化输出的若干问题
来源 :https://my.oschina.net/Adven/blog/3036567
使用springboot-web编写rest接口,接口需要返回json数据,目前国内比较常用的fastjson使用比较方便,但是SpringBoot默认使用的Jackson,替换的时候有时候因为其他组件也使用到了jackson,所以无法100%成功替换。 不喜欢使用jackson主要是jackson对格式化输出支持不太友好,自己使用的时候遇到许多坑,至今也没把坑填好,所以一直就不待见它,有时候又不得不用。 下面总结一下Fastjson/Jackson两种对json序列化+格式化输出的配置总结。
1.Jackson方式(SpringBoot中的默认方式):
1.1application.yml配置文件
spring:
jackson:
#日期格式化
date-format: yyyy-MM-dd HH:mm:ss
serialization:
#格式化输出
indent_output: true
- 网上提供的方案,可是实际配置并不能生效
1.2使用JavaConfig文件配置Jackson格式化输出
@Configuration
public class JacksonConfig extends WebMvcConfigurationSupport { /**
* 格式化输出配置
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter jacksonConverter = (MappingJackson2HttpMessageConverter) converter;
jacksonConverter.setPrettyPrint( true ); // 实际使用生效
}
}
}
}
2.Fastjson方式
2.1引入fastjson,排除jackson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency> <!--排除jackson-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--,排除jackson(根据实际情况,下面的非必须)-->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.4.RELEASE</version>
<!--<exclusions>-->
<!--<exclusion>-->
<!--<groupId>com.fasterxml.jackson.core</groupId>-->
<!--<artifactId>jackson-databind</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>${spring-boot.version}</version>
<scope>compile</scope>
<!--<exclusions>-->
<!--<exclusion>-->
<!--<groupId>com.fasterxml.jackson.core</groupId>-->
<!--<artifactId>jackson-databind</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
</dependency>
2.2 使用JavaConfig配置
- SpringBoot中fastjson的配置有两种方式:
2.2.1 方式一
配置Bean 使用fastjson的方式实现HttpMessageConverters
@Configuration
public class FastJSONConfig {
/**
* Fastjson
*
* @return
*/
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastJsonHttpMessageConverter.setSupportedMediaTypes(mediaTypes);
fastJsonConfig.setSerializerFeatures(
SerializerFeature.DisableCircularReferenceDetect, //禁用循环引用
SerializerFeature.PrettyFormat,
SerializerFeature.IgnoreNonFieldGetter
);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> converter = fastJsonHttpMessageConverter;
return new HttpMessageConverters(converter);
}
}
2.2.2方式二
- Spring5.x中实现WebMvcConfigurer接口,并重写configureMessageConverters方法,向其中添加FastJsonHttpMessageConverter
@Configuration
public class FastJsonHttpConverterConfig implements WebMvcConfigurer {
// fastjson配置
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Iterator<HttpMessageConverter<?>> iterator = converters.iterator();
while(iterator.hasNext()){
HttpMessageConverter<?> converter = iterator.next();
if(converter instanceof MappingJackson2HttpMessageConverter){
iterator.remove();
}
}
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty, // List类型字段为null时输出[]而非null
SerializerFeature.WriteMapNullValue, // 显示空字段
SerializerFeature.WriteNullStringAsEmpty, // 字符串类型字段为null时间输出""而非null
SerializerFeature.WriteNullBooleanAsFalse, // Boolean类型字段为null时输出false而null
SerializerFeature.PrettyFormat, // 美化json输出,否则会作为整行输出
SerializerFeature.WriteNullNumberAsZero, // 数值字段如果为null,输出为0,而非null
SerializerFeature.WriteNullBooleanAsFalse, // Boolean字段如果为null,输出为false,而非null
SerializerFeature.WriteDateUseDateFormat, // 时间格式yyyy-MM-dd HH: mm: ss
SerializerFeature.DisableCircularReferenceDetect); // 禁用循环引用检测
converter.setFastJsonConfig(config);
converters.add(converter);
List<MediaType> supportedMediaTypes = new ArrayList<>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
supportedMediaTypes.add(MediaType.APPLICATION_PDF);
supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
supportedMediaTypes.add(MediaType.APPLICATION_XML);
supportedMediaTypes.add(MediaType.IMAGE_GIF);
supportedMediaTypes.add(MediaType.IMAGE_JPEG);
supportedMediaTypes.add(MediaType.IMAGE_PNG);
supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
supportedMediaTypes.add(MediaType.TEXT_HTML);
supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
supportedMediaTypes.add(MediaType.TEXT_PLAIN);
supportedMediaTypes.add(MediaType.TEXT_XML);
converter.setSupportedMediaTypes(supportedMediaTypes);
}
}
2.2.3 总结
- fastjson替换jackson并不能保证100%成功,但是都能最终实现格式化输出。HttpMessageConverter的具体实现需要深入阅读源码,从源码上进一步寻找答案。
- 使用fastjson替换在自己DIY的OAuth2-SSO项目中认证服务器无法成功替换,最后基于1中jackson最终实现格式化输出。
3.附Restful接口输出json数据
@RestController
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class); /**
* 资源服务器提供的受保护接口
* @param authentication
* @return
*/
@GetMapping(value = "/user",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Authentication getUserInfo(Authentication authentication) {
logger.info("authentication resource: user {}", authentication);
System.out.println(JSON.toJSONString(authentication, SerializerFeature.PrettyFormat));
return authentication;
} /**
* 提供一个/user/me接口供客户端来获得用户的凭证
* @param principal
* @return
*/
@GetMapping(value = "/user/me",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Principal getUserPrincipal(Principal principal) {
System.out.println("com.acanx.sso.oauthserver.controller.UserController#user Principal:"+principal);
logger.info("Principal: user {}", principal);
System.out.println(JSON.toJSONString(principal, SerializerFeature.PrettyFormat));
return principal;
}
}
SpringBoot中使用Fastjson/Jackson对JSON序列化格式化输出的若干问题的更多相关文章
- Java下用Jackson进行JSON序列化和反序列化(转)
Java下常见的Json类库有Gson.JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的J ...
- Json序列化指定输出字段 忽略属性
DataContract 服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务 ...
- python json.dumps()函数输出json格式,使用indent参数对json数据格式化输出
在python中,要输出json格式,需要对json数据进行编码,要用到函数:json.dumps json.dumps() :是对数据进行编码 #coding=gbkimport json dict ...
- python中列表和元组的操作(结尾格式化输出小福利)
一. 列表 1. 查 names = "YanFeixu WuYifan" names_1 = ["YanFeixu"," WuYifan" ...
- 用Jackson进行Json序列化时的常用注解
Jackson时spring boot默认使用的json格式化的包,它的几个常用注解: @JsonIgnore 用在属性上面,在序列化和反序列化时都自动忽略掉该属性 @JsonProperty(&qu ...
- 关于spring中请求返回值的json序列化/反序列化问题
https://cloud.tencent.com/developer/article/1381083 https://www.jianshu.com/p/db07543ffe0a 先留个坑
- 在JAVA中把JSON数据格式化输出到控制台
public class ForMatJSONStr { public static void main(String[] args) { String jsonStr = "{\" ...
- JSON.stringify() 格式化 输出log
调试程序的过程中,我们打印一个日志: console.log(object);,其中object是任意的一个json对象. 在控制台就会看到[object object],而看不到具体的内容. 我们可 ...
- springboot中json转换LocalDateTime失败的bug解决过程
环境:jdk1.8.maven.springboot 问题:前端通过json传了一个日期:date:2019-03-01(我限制不了前端开发给到后端的日期为固定格式,有些人就是这么不配合), ...
随机推荐
- 监控实战Prometheus+Grafana
这期的分享是监控实战,其实不想写这篇的,因为网上相关的文章也挺多的,但是出于光说不练都是假把式,而且也想告诉你:当帅气的普罗米修斯(Prometheus)遇到高颜值的格拉法纳(Grafana)究竟会擦 ...
- G1垃圾回收器
垃圾回收器的发展历程 背景 01.G1解决的问题 G1垃圾回收器是04年正式提出,12开始正式支持,在17年作为JDK9默认的垃圾处理器. 在04年的时候,java程序堆的内存越来越大,从而导致程序中 ...
- CSS实现文本,DIV垂直居中
https://blog.csdn.net/linayangoo/article/details/88528774 1.水平居中 1.行内元素水平居中 text-align:center; 利用tex ...
- psutil运维必会模块
目录 psutil介绍 安装psutil 获取CPU信息 获取内存信息 获取磁盘信息 获取网络信息 获取进程信息 psutil介绍 用Python来编写脚本简化日常的运维工作是Python的一个重要用 ...
- python 爬虫之 urllib库
文章更新于:2020-03-02 注:代码来自老师授课用样例. 一.初识 urllib 库 在 python2.x 版本,urllib 与urllib2 是两个库,在 python3.x 版本,二者合 ...
- 关于wget下载jdk问题解决
问题: 直接从jdk官网下载会出现: 正在解析主机 login.oracle.com (login.oracle.com)... 156.151.58.18正在连接 login.oracle.com ...
- css3新的选择器
CSS3新的选择器 ele[att^="val"] /*属性att的值以val开头的元素*/ ele[att$="val"] /*属性att的值以val结尾的元 ...
- 路由与交换,cisco路由器配置,静态路由
网络是一个大型的拓扑结构,在路由表中,最重要的是管理距离和度量值 管理距离 管理距离用来确定路由的优先级.管理距离的范围是0-255之间的整数值.值越低代表优先级越高.0代表最高优先级.并且只有直连路 ...
- 34.2 字节流 InputStreamReader OutputStreamWriter
使用方法同字符流,不一样的是数据类型是字节 copydemo public static void main(String[] args) throws IOException { InputStre ...
- C语言实现顺序表(顺序存储结构)
顺序表(顺序存储结构)及初始化过程详解 顺序表,全名顺序存储结构,是线性表的一种.通过<线性表>一节的学习我们知道,线性表用于存储逻辑关系为"一对一"的数据,顺序表自然 ...