springboot jackson日期和BigDecimal处理
- 概述
- jackson简单使用
- springboot使用
- 自定义序列化属性
- 序列化
概述
jackson简单使用
springboot是使用jackson来序列化和反序列化json数据,而jackson主要用到的是ObjectMapper类,
如以下简单实例
package com.test.jacson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class Test {
@Data
@AllArgsConstructor
@NoArgsConstructor
static class User {
private String name;
private Integer age;
}
public static void main(String[] args) throws JsonProcessingException {
User user = new User("abc", 12);
ObjectMapper objectMapper = new ObjectMapper();
String value = objectMapper.writeValueAsString(user);
System.out.println(value);
User user1 = objectMapper.readValue(value, User.class);
System.out.println(user1);
}
}
springboot使用
配置类,如下,可以看出自动配置了ObjectMapper,需要Jackson2ObjectMapperBuilder设置属性,比如对日期的序列化和反序列化。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
static class JacksonObjectMapperConfiguration {
@Bean
@Primary
@ConditionalOnMissingBean
ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.createXmlMapper(false).build();
}
}
Jackson2ObjectMapperBuilder对象的配置,从List customizers这里可以看出,只需把Jackson2ObjectMapperBuilderCustomizer放到spring容器,即可对jackson的一些特性做自定义配置。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
static class JacksonObjectMapperBuilderConfiguration {
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(ApplicationContext applicationContext,
List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.applicationContext(applicationContext);
customize(builder, customizers);
return builder;
}
private void customize(Jackson2ObjectMapperBuilder builder,
List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
for (Jackson2ObjectMapperBuilderCustomizer customizer : customizers) {
customizer.customize(builder);
}
}
}
自定义序列化属性
如下代码,主要配置了一些序列化的属性,Date类型转化为yyyy-MM-dd HH:mm:ss格式,LocalDateTime也是为该格式,并且对返回给前端的BigDecimal类型不返回科学计数法。
package com.ax.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
@Component
public class CustomizerJackson2ObjectMapperBuilder implements Jackson2ObjectMapperBuilderCustomizer {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
builder.dateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
builder.modules(javaTimeModule, new Jdk8Module(), new ParameterNamesModule());
builder.serializerByType(BigDecimal.class, new JsonSerializer<BigDecimal>() {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(value.stripTrailingZeros().toPlainString());
}
});
}
}
以上配置方式是统一处理,也可以对日期单独处理,使用@JsonFormat注解
序列化
从前端可能会传过来类似于yyyy-MM-dd HH:mm:ss这种格式,后端希望以Date或LocalDateTime来接收,可以使用@DateTimeFormat来标注,如下
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime time;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;