springboot 使用@JsonComponent自定义JSON序列化程序和反序列化程序
如果使用Jackson对JSON数据进行序列化和反序列化,则可能需要编写自己的 JsonSerializer 和 JsonDeserializer 。自定义序列化程序通常通过模块向Jackson注册,但Spring Boot提供了一个可选的@JsonComponent注释,使直接注册SpringBean更加容易。
您可以直接在 JsonSerializer 或 JsonDeserializer 实现上使用 @JsonComponent注释,注释允许我们将带注释的类公开为Jackson序列化器和/或反序列化器,而无需手动将其添加到ObjectMapper。您还可以在包含序列化程序/反序列化程序作为内部类的类上使用它
package com.example.demo.config;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.jackson.JsonComponent;
/**
* @author lwb516
*
*/
@JsonComponent
public class Java8Date2TimestampJsonComponent {
/**
* 当前时区偏移量
*/
private static final ZoneOffset CURRENT_ZONE_OFFSET = ZoneOffset.ofHours(8);
/**
* LocalDate 序列化
*/
public static class LocalDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(localDate.atStartOfDay(CURRENT_ZONE_OFFSET).toInstant().toEpochMilli());
}
}
/**
* LocalDate 反序列化
*/
public static class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return Instant.ofEpochMilli(Long.valueOf(jsonParser.getText())).atZone(CURRENT_ZONE_OFFSET).toLocalDate();
}
}
private static LocalDate actualDate = Instant.ofEpochMilli( 0L ) .atOffset(CURRENT_ZONE_OFFSET).toLocalDate();
/**
* LocalTime 序列化
*/
public static class LocalTimeSerializer extends JsonSerializer<LocalTime> {
@Override
public void serialize(LocalTime localTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(LocalDateTime.of(actualDate,localTime).toInstant(CURRENT_ZONE_OFFSET).toEpochMilli());
}
}
/**
* LocalTime 反序列化
*/
public static class LocalTimeDeserializer extends JsonDeserializer<LocalTime> {
@Override
public LocalTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return Instant.ofEpochMilli(Long.valueOf(jsonParser.getText())).atZone(CURRENT_ZONE_OFFSET).toLocalTime();
}
}
/**
* LocalDateTime 序列化
*/
public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(localDateTime.toInstant(CURRENT_ZONE_OFFSET).toEpochMilli());
}
}
/**
* 当前时区偏移量
*/
/**
* LocalTime 反序列化
*/
public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return Instant.ofEpochMilli(Long.valueOf(jsonParser.getText())).atZone(CURRENT_ZONE_OFFSET).toLocalDateTime();
}
}
}
需要注意的是不能再使用ObjectMapper进行注册,否则可能会导致不起作用
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package com.example.demo.entity;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private String code;
private Long parentId;
private Date createTime;
private LocalDate localDate;
private LocalTime localTime;
private LocalDateTime localDateTime;
}
Controller
package com.example.demo.controller;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import com.example.demo.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lwb516
* @date 2019-06-18 05:57:44
* @since jdk 1.8
*/
@RestController
@RequestMapping("user-api/job")
public class JobController {
/**
*
* @return
*/
@PostMapping("/updateJob")
public String updateByPrimaryKeySelective(@RequestBody User user) {
return "result";
}
@GetMapping("/getUser")
@ResponseBody
public User getJob( ) {
User u = new User();
u.setLocalDate(LocalDate.now());
u.setLocalTime(LocalTime.now());
u.setLocalDateTime(LocalDateTime.now());
u.setCode("dsfasd");
u.setId(213L);
return u;
}
}
getUser 返回
{
"id": 213,
"name": null,
"code": "dsfasd",
"parentId": null,
"createTime": null,
"localDate": 1568217600000,
"localTime": 30937914,
"localDateTime": 1568277337914
}
updateJob RequestBody
{"localDate":1561478400000,"createtime":1561615193000,"localDateTime":1561651210300,"name":"12345678","id":12,"localTime":2728988000,,"status":1}
后台打印
user=User(id=12, name=12345678, code=null, parentId=null, createTime=null, localDate=2019-06-26, localTime=22:03:08, localDateTime=2019-06-28T00:00:10.300)