容器内JAX-RS Client的ISO8601日期序列化问题
解决JEE7(WildFly10)中LocalDateTime序列化为ISO8601字符串的问题
这个场景我太熟悉了——WildFly10默认用Jackson处理JSON序列化,而Java 8的LocalDateTime默认会被拆成包含年、月、日等字段的复杂JSON对象,完全不符合API期望的ISO8601格式字符串。下面给你两个最实用的解决思路:
方法一:给单个DTO字段添加Jackson注解(快速解决单个场景)
如果只有ItemDTO这一个类需要处理,直接在timestamp字段上添加@JsonFormat注解,指定序列化格式即可:
class ItemDTO { private String name; // 强制序列化为指定格式的ISO8601字符串 @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS") private LocalDateTime timestamp; // 默认构造方法、getter、setter省略 }
这个注解会告诉Jackson把LocalDateTime直接转成你需要的2018-01-01T01:01:01.001格式字符串,完全匹配API的要求。
方法二:全局配置Jackson ObjectMapper(统一处理所有时间字段)
如果你的应用里有多个DTO都用到了LocalDateTime,全局配置会更高效。WildFly10的JAX-RS基于Resteasy,我们可以通过自定义ContextResolver来统一配置Jackson的序列化规则:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; import java.time.format.DateTimeFormatter; // 让JEE容器自动扫描并加载这个配置类 @Provider public class JacksonGlobalConfig implements ContextResolver<ObjectMapper> { private final ObjectMapper objectMapper; public JacksonGlobalConfig() { objectMapper = new ObjectMapper(); // 注册Jackson处理Java 8时间类型的模块 JavaTimeModule timeModule = new JavaTimeModule(); // 自定义LocalDateTime的序列化格式 LocalDateTimeSerializer dateTimeSerializer = new LocalDateTimeSerializer( DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS") ); timeModule.addSerializer(LocalDateTime.class, dateTimeSerializer); objectMapper.registerModule(timeModule); } @Override public ObjectMapper getContext(Class<?> type) { return objectMapper; } }
要确保这个配置类能被JEE容器扫描到——要么把它放在你的@ApplicationPath注解标注的应用类所在的包下,要么在web.xml里显式配置(不过JEE7推荐注解扫描)。配置完成后,所有的LocalDateTime字段都会自动序列化为指定的ISO8601格式字符串。
注意事项
WildFly10自带的Jackson版本已经包含JavaTimeModule(Jackson 2.6+支持),所以不需要额外引入Jackson的依赖,直接用就行。如果你的项目里自己引入了Jackson依赖,要注意版本和WildFly自带的版本兼容,避免冲突。
内容的提问来源于stack exchange,提问作者Cec
相关产品推荐
相关产品推荐

