Jackson
是另一个流行的JSON
序列化和反序列化库,具有以下特点
Jackson
采用了高效的JSON
解析算法和字节码生成技术,使得其序列化和反序列化速度非常快。Jackson
能够序列化所有类型的对象,包括复杂类型和自定义类型。Jackson
提供了很多高级特性,如 JSON 映射、注解和 JSON 树模型
等,使得其在企业级应用中得到广泛应用。依赖
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.26version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
<scope>compilescope>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.13.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.13.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.13.0version>
dependency>
dependencies>
使用示例
package org.example.demo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class JacksonExample {
public static void main(String[] args) throws JsonProcessingException {
// 将 Java 对象转换为 JSON 字符串
User user = new User("Tom", 18);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
System.out.println(json); // {"name":"Tom","age":18}
// 将 JSON 字符串转换为 Java 对象
String jsonStr = "{\"name\":\"Tom\",\"age\":18}";
User user2 = mapper.readValue(jsonStr, User.class);
System.out.println(user2.getName() + " " + user2.getAge()); // Tom 18
}
@Data
@NoArgsConstructor
@AllArgsConstructor
static class User {
private String name;
private int age;
}
}
Gson
是JSON
序列化和反序列化库。Gson
也是一个非常流行的JSON
序列化和反序列化库,具有以下特点
简单易用:Gson
的使用非常简单,只需要在项目中引入 gson.jar
,即可开始使用。
高度灵活性:Gson
可以很方便地处理各种类型的对象,包括 Java 8
的新特性,如LocalDate
和 LocalDateTime
扩展性强:Gson
提供了很多扩展点,可以方便地进行自定义扩展。
依赖
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.26version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
<scope>compilescope>
dependency>
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>2.8.9version>
dependency>
dependencies>
使用示例
package org.example.demo;
import com.google.gson.Gson;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class GsonExample {
public static void main(String[] args) {
// 将 Java 对象转换为 JSON 字符串
User user = new User("Tom", 18);
Gson gson = new Gson();
String json = gson.toJson(user);
System.out.println(json); // {"name":"Tom","age":18}
// 将 JSON 字符串转换为 Java 对象
String jsonStr = "{\"name\":\"Tom\",\"age\":18}";
User user2 = gson.fromJson(jsonStr, User.class);
System.out.println(user2.getName() + " " + user2.getAge()); // Tom 18
}
@Data
@NoArgsConstructor
@AllArgsConstructor
static class User {
private String name;
private int age;
}
}
Fastjson
是阿里巴巴开源的JSON
序列化和反序列化库,由于其高效性和稳定性,成为目前使用最广泛的JSON
序列化和反序列化库之一。以下是Fastjson
的主要特点
高性能:Fastjson
采用了许多优化措施,如字节码生成和对象池,使得其反序列化速度非常快,序列化速度也很快。
支持全类型序列化:Fastjson
能够序列化所有类型的对象,包括复杂类型和自定义类型。
兼容性好:Fastjson
支持 JSON
标准规范,并且与其他 JSON
库兼容。
使用方便:Fastjson
的使用非常简单,几乎不需要配置,只需要在项目中引入 fastjson.jar
,即可开始使用。
依赖
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.26version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
<scope>compilescope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.78version>
dependency>
dependencies>
用法
package org.example.demo;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class FastjsonExample {
public static void main(String[] args) {
// 将 Java 对象转换为 JSON 字符串
User user = new User("Tom", 18);
String json = JSON.toJSONString(user);
System.out.println(json); // {"age":18,"name":"Tom"}
// 将 JSON 字符串转换为 Java 对象
String jsonStr = "{\"age\":18,\"name\":\"Tom\"}";
User user2 = JSON.parseObject(jsonStr, User.class);
System.out.println(user2.getName() + " " + user2.getAge()); // Tom 18
}
@Data
@NoArgsConstructor
@AllArgsConstructor
static class User {
private String name;
private int age;
}
}
介绍
在
Spring Boot
中,JSON
序列化和反序列化默认使用Jackson
库,因此不需要额外配置Jackson
的依赖。但如果想使用Fastjson
或Gson
库,可以通过以下方式配置Maven
依赖
依赖导入未发生变化
Jackson: 不需要添加,因为当添加spring-boot-starter-web
的依赖时内部已经添加了
jackson |
---|
因为使用spring-boot-starter-web
内部已经有jackson
,为了使用gson
,所以排除jackson
的依赖
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jsonartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>2.8.9version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
dependencies>
yml
# 可以配置的一些参数
spring:
gson:
# 用于指定日期格式化的格式字符串,将 Java 对象中的日期类型属性转换成对应的字符串形式。示例配置 yyyy-MM-dd HH:mm:ss 表示使用标准的日期格式将日期类型属性转换成字符串形式。如果不配置该属性,则使用 Gson 默认的日期格式化方式。
date-format: yyyy-MM-dd HH:mm:ss
# disable-html-escaping:用于指定是否禁用 HTML 转义,当序列化 HTML 内容时,开启该选项可以防止 XSS 攻击。该属性默认值为 false,即默认启用 HTML 转义。
disable-html-escaping: true
# disable-inner-class-serialization:用于指定是否禁用序列化内部类,默认值为 false,即序列化内部类。
disable-inner-class-serialization: true
# enable-complex-map-key-serialization:用于指定是否启用复杂类型的 Map 键的序列化,默认值为 false,即禁用复杂类型的 Map 键的序列化。
enable-complex-map-key-serialization: true
# exclude-fields-without-expose-annotation:用于指定是否排除未标注 @Expose 注解的字段,默认值为 false,即不排除未标注 @Expose 注解的字段。
exclude-fields-without-expose-annotation: true
# field-naming-policy:用于指定字段命名策略,默认值为 IDENTITY,即使用 Java 对象中的字段名称作为 Gson 中的字段名称。其他可选值包括 LOWER_CASE_WITH_UNDERSCORES、UPPER_CAMEL_CASE 和 UPPER_CAMEL_CASE_WITH_SPACES 等。
field-naming-policy: LOWER_CASE_WITH_UNDERSCORES
# serialize-nulls:用于指定是否序列化 null 值,默认值为 false,即不序列化 null 值。
serialize-nulls: true
也可以通过GsonBuilder
实现,两种方式选择一种
@Configuration
public class GsonConfig {
@Bean
public GsonBuilder gsonBuilder() {
GsonBuilder builder = new GsonBuilder();
builder.setDateFormat("yyyy-MM-dd HH:mm:ss");
return builder;
}
}
配置前 | 配置后(builder.setDateFormat("yyyy-MM-dd HH:mm:ss"); ) |
---|---|
使用程度较低
排除依赖
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jsonartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.78version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
dependencies>
注意点
需要注意的是,使用
Fastjson 或 Gson
时,要保证它们的依赖包的版本与Spring Boot
的依赖包版本兼容,避免出现不必要的冲突和错误。在
SpringMVC
框架 中,jackson
和gson
已经自动配置好了,只需要添加相应的依赖,而Fastjson
则需要开发者手动配置HttpMessageConverter
,直接启动会出现如下错误
Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation] |
---|
解决方法
package com.example.jsondemo.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 使用 Fastjson 作为 HTTP 消息转换器
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
converter.setFastJsonConfig(getFastJsonConfig());
converters.add(converter);
}
/**
* 配置 Fastjson
*/
private FastJsonConfig getFastJsonConfig() {
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteDateUseDateFormat);
// 也可以直接在 yml 文件中配置
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
return config;
}
}
配置前 | 配置后 |
---|---|
yml
spring:
fastjson:
date-format: yyyy-MM-dd HH:mm:ss
测试
@SpringBootTest
class JsonDemoApplicationTests {
@Test
void contextLoads() {
User user = new User();
user.setUid("1001");
user.setUname("coder-itl");
user.setAddress("http://coderitl.github.io");
user.setCreateTime(new Date(System.currentTimeMillis()));
String toJSONString = JSON.toJSONString(user);
System.out.println(toJSONString);
// 反序列化
}
}
序列化: 对象转换为JSON
反序列化: JSON
转换为对象
如何实现序列化和反序列化这个过程的?
由转换器:HttpMessageConverter
实现
在
Spring
框架中,HttpMessageConverter
是一个用于在消息传递时将消息从一种格式转换为另一种格式的接口。它的主要作用是帮助在不同的客户端和服务之间传递消息,并确保消息在传递过程中能够正确地序列化和反序列化。
Spring
框架中提供了多个预定义的HttpMessageConverter
实现,可以根据不同的需求选择使用。常用的消息格式包括JSON、XML、二进制
等。配置
HttpMessageConverter
可以通过在Spring
应用程序上下文中注册HttpMessageConverter
类型的Bean
来实现。具体语法如下
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
}
}
上面的示例配置了一个
MappingJackson2HttpMessageConverter
对象,用于将Java
对象转换为JSON
格式的消息。在这个例子中,我们使用了Spring 的 Java
配置方式,并实现了WebMvcConfigurer
接口中的configureMessageConverters()
方法来注册我们自己的MessageConverter
实现。需要注意的是,当我们自定义
MessageConverter
时,必须添加到converters
列表的前面,以确保它是在默认的转换器之前被调用的。此外,我们也可以通过重写extendMessageConverters()
方法来添加自定义的MessageConverter
,这个方法会在默认的转换器之后调用。