来源 :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序列化格式化输出的若干问题的更多相关文章

  1. Java下用Jackson进行JSON序列化和反序列化(转)

    Java下常见的Json类库有Gson.JSON-lib和Jackson等,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的J ...

  2. Json序列化指定输出字段 忽略属性

    DataContract 服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务 ...

  3. python json.dumps()函数输出json格式,使用indent参数对json数据格式化输出

    在python中,要输出json格式,需要对json数据进行编码,要用到函数:json.dumps json.dumps() :是对数据进行编码 #coding=gbkimport json dict ...

  4. python中列表和元组的操作(结尾格式化输出小福利)

    一. 列表 1. 查 names = "YanFeixu WuYifan" names_1 = ["YanFeixu"," WuYifan" ...

  5. 用Jackson进行Json序列化时的常用注解

    Jackson时spring boot默认使用的json格式化的包,它的几个常用注解: @JsonIgnore 用在属性上面,在序列化和反序列化时都自动忽略掉该属性 @JsonProperty(&qu ...

  6. 关于spring中请求返回值的json序列化/反序列化问题

    https://cloud.tencent.com/developer/article/1381083 https://www.jianshu.com/p/db07543ffe0a 先留个坑

  7. 在JAVA中把JSON数据格式化输出到控制台

    public class ForMatJSONStr { public static void main(String[] args) { String jsonStr = "{\" ...

  8. JSON.stringify() 格式化 输出log

    调试程序的过程中,我们打印一个日志: console.log(object);,其中object是任意的一个json对象. 在控制台就会看到[object object],而看不到具体的内容. 我们可 ...

  9. springboot中json转换LocalDateTime失败的bug解决过程

    环境:jdk1.8.maven.springboot 问题:前端通过json传了一个日期:date:2019-03-01(我限制不了前端开发给到后端的日期为固定格式,有些人就是这么不配合),      ...

随机推荐

  1. Blazor入门笔记(5)-数据绑定

    1.环境 VS2019 16.5.1 .NET Core SDK 3.1.200 Blazor WebAssembly Templates 3.2.0-preview2.20160.5 2.默认绑定 ...

  2. webpack4.x 从零开始配置vue 项目(三)

    目标 babel 转换ES6 语法 postCss 增强css功能,如自动增加前缀 vue-loader 解析vue 文件 实现基本的vue项目开发环境,打包等 Babel 由于浏览器对es6语法兼容 ...

  3. linux下使用笔记本的相关设置

    目录 无线连接 Wi-Fi 蓝牙 触摸板 电源管理 电源管理工具 电源相关行为的响应动作 按键和盖子的响应动作 电池低电量的响应动作 处理器调整 调频工具 关闭睿频 intel_pstate 休眠配置 ...

  4. Nginx 是如何处理 HTTP 头部的?

    Nginx 处理 HTTP 头部的过程 Nginx 在处理 HTTP 请求之前,首先需要 Nginx 的框架先和客户端建立好连接,然后接收用户发来的 HTTP 的请求行,比如方法.URL 等,然后接收 ...

  5. QT-day1 创建项目

  6. 【电商】性能测试网站搭建:XAMPP1.8+DBShop1.3

    1.安装准备 1.1软件版本 XAMPP的版本:XAMPP 1.8.2 DBShop的版本:DBShop 1.3   1.2.安装环境 我的环境:win10 win7,win10都可以运行的,安装步骤 ...

  7. 【php】文件系统

    一. 了解文件: a) 我们在Windows当中已知众多种文件类型:png.jpeg.jpg.gif.mp3.mp4.avi.rmvb.txt.doc.exl.ppt.php.exe b) 无论我们w ...

  8. qq群排名靠前最新方法

    QQ群排名这几年是越来越火,因为很多灰产业都选择做QQ群排名,毕竟没有那么严,那么要做QQ群排名虽然不难,但是还是需要一点技术和软件的. https://url.cn/5JbR4C8 QQ群排名分为如 ...

  9. PHP程序员的能力水平层次(二)

    PHPer的定义:PHPer是以PHP程序编写为主要工作,其他方面略有涉及的一种职业人士,大家所说的程序猿. 对PHPer的等级划分 PHP 爱好者 (半个PHPer) PHP 初学者 (PHP Be ...

  10. 33.1 File 获取目录下的所有文件及子目录

    重要获取功能 String[] list() 返回当前路径下所有的文件和文件夹名称 //注意:只有指向文件夹的File对象才可以调用该方法(指向文件的file对象使用list会报错npe) File[ ...