使用 java.time.LocalDateTime(续):全局返回时间戳给前端
Java 8
PostgreSQL 14
spring-boot-starter-parent 2.7.3
mybatis-plus-boot-starter 3.4.3.4
--
ben发布于博客园
前文:使用 java.time.LocalDateTime
https://www.cnblogs.com/luo630/p/17077756.html
在 参考文档#1 中,提供了 返回时间类型给前端时 统一使用时间戳 的方案:修改 ObjectMapper。
本文在示例项目 bootweb 中实现了此方案。
ben发布于博客园
在 bootweb 中,自动生成了 名为 jacksonObjectMapper 的 bean,类型为:class com.fasterxml.jackson.databind.ObjectMapper,
位于 jackson-databind-2.13.3.jar 中(Spring Boot 自带)。
修改该 bean 的 serializerFactory 即可——单独处理 LocalDate、LocalDateTime 类型。
示例代码:DateBeanSerializerModifier.java
继承了 com.fasterxml.jackson.databind.ser.BeanSerializerModifier 类,其中包含 两个静态类 LocalDateConverter、LocalDateTimeConverter,分别用于转换 LocalDate、LocalDateTime。
(照抄 参考资料#1)
DateBeanSerializerModifier.java
package com.lib.bootweb.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
public class DateBeanSerializerModifier extends BeanSerializerModifier {
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
for (BeanPropertyWriter bpw : beanProperties) {
if (isLocalDateType(bpw)) {
bpw.assignSerializer(new LocalDateConverter());
} else if (isLocalDateTimeType(bpw)) {
bpw.assignSerializer(new LocalDateTimeConverter());
}
}
return beanProperties;
}
private boolean isLocalDateType(BeanPropertyWriter bpw) {
Class<?> clazz = bpw.getType().getRawClass();
return LocalDate.class.isAssignableFrom(clazz);
}
private boolean isLocalDateTimeType(BeanPropertyWriter bpw) {
Class<?> clazz = bpw.getType().getRawClass();
return LocalDateTime.class.isAssignableFrom(clazz);
}
public static class LocalDateConverter extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
// +8 可以修改为本地的 TODO
gen.writeNumber(((LocalDate)value).atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli());
}
}
public static class LocalDateTimeConverter extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
// +8 可以修改为本地的 TODO
gen.writeNumber(((LocalDateTime) value).toInstant(ZoneOffset.of("+8")).toEpochMilli());
}
}
}
修改 ObjectMapper:ben发布于博客园
本文采用在一个 ApplicationRunner 对象中实现。
package com.lib.bootweb.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/**
* 修改默认的 ObjectMapper Bean
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class ModifyObjectMapperRunner implements ApplicationRunner {
private final ObjectMapper objectMapper;
@Override
public void run(ApplicationArguments args) throws Exception {
objectMapper.setSerializerFactory(
objectMapper.getSerializerFactory()
.withSerializerModifier(new DateBeanSerializerModifier()) // 上文的新类
);
log.info("ModifyObjectMapperRunner END");
}
}
ben发布于博客园
测试的VO:SomeInfo20VO、SomeInfo21VO、SomeInfo22VO,后面两个有使用 @JsonFormat 注解。
ben发布于博客园
新增测试接口:/api/someInfo/getWithTyped
@GetMapping(value = "getWithType")
public Object getByIdWithType(@RequestParam String id, @RequestParam Integer type) {
SomeInfoPO ent = someInfoService.getById(id);
if (ent == null) {
return null;
}
switch (type) {
case 20:
SomeInfo20VO ret4 = new SomeInfo20VO();
BeanUtils.copyProperties(ent, ret4);
return ret4;
case 21:
SomeInfo21VO ret5 = new SomeInfo21VO();
BeanUtils.copyProperties(ent, ret5);
return ret5;
case 22:
SomeInfo22VO ret6 = new SomeInfo22VO();
BeanUtils.copyProperties(ent, ret6);
return ret6;
default:
return null;
}
}
调用接口 /api/someInfo/getWithType,测试结果:ben发布于博客园
无论入参的 type 是 20、21、22,返回的 createTime 都是时间戳。
注意,
本文中修改 ObjectMapper bean 的方式还需优化 TODO
关于 java.util.Date 类型也返回时间戳给前端,仅需修改 Spring Boot 项目的配置即可:
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=true
即可。
---END---ben发布于博客园
本文链接:
https://www.cnblogs.com/luo630/p/17080130.html
ben发布于博客园
参考资料
1、SpringBoot中对于LocalDate和LocalDateTime如何返回时间戳
https://www.jianshu.com/p/21309e1a08be
2020.11.03 15:18:18
原文:http://tech.cnhnb.com/post/9
2、
ben发布于博客园