问题:当我们的REST服务返回带有日期/日期时间字段的对象时,这些字段被编码为JSON格式的复杂结构:
...
"createdTimestamp": {
"offset": {
"totalSeconds": 0,
"id": "Z",
"rules": {
"fixedOffset": true,
"transitionRules": [],
"transitions": []
}
},
"nano": 257353000,
"hour": 16,
"minute": 5,
"second": 25,
"month": "OCTOBER",
"year": 2017,
"dayOfMonth": 5,
"dayOfWeek": "THURSDAY",
"dayOfYear": 278,
"monthValue": 10
},
...
我希望将这些时态数据类型序列化为一个简单的格式,如" 2017-10-05T16:05:25"。
该项目最初基于Java 7 API,java.util.Date
在任何地方都使用过 - 而且它有效。当我切换到Java 8并开始使用新的java.time
类时,除了将日期/时间对象序列化为JSON之外,一切都有效。
我知道我可以再次使用java.util.Date
类型,但我更喜欢使用新的数据类型。
REST服务使用Swagger定义并使用Maven构建。使用swagger-codegen-maven-plugin
,具有以下配置:
jaxrs-cxf-cdi
java8
以下是其他相关库的版本(在POM中定义):
swagger-codegen
:2.2.3 cxf-bundle-jaxrs
:2.7.18 gson
:2.8.1 我对REST服务很陌生(我直到最近才使用SOAP服务)。
我试图找到一种自定义序列化输出到JSON的方法,但没有成功。我发现OffsetDateTime
应该是受支持的类型(关于序列化),应该很好地序列化。我还尝试配置Maven插件以使用Java库' java8-localdatetime'使用LocalDateTime
类型 - 但它没有帮助 - LocalDateTime
的序列化实例仍然被转换为复杂的JSON对象。
答案 0 :(得分:0)
今天我遇到了同样的问题,我的方法是遵循从生成的ApiClient开始的依赖项:
private DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
// create a message converter for jackson using a prepared objectMapper
ObjectMapper mapper = objectMapper();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper);
rest = new RestTemplate();
// add the converter at first position to converter list of the rest template
rest.getMessageConverters().add(0, converter );
// finally create the ApiClient with the configured restTemplate
ApiClient defaultClient = new ApiClient(rest);
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.findAndRegisterModules();
JavaTimeModule module = new JavaTimeModule();
module.addDeserializer(OffsetDateTime.class, new StdDeserializer<OffsetDateTime>(OffsetDateTime.class) {
@Override
public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
return OffsetDateTime.parse(p.getText());
}
});
module.addSerializer(OffsetDateTime.class, new StdSerializer<OffsetDateTime>(OffsetDateTime.class) {
@Override
public void serialize( OffsetDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeString( dtf.format( value ));
}
});
// possible alternative to custom serializer if default format is sufficient
//objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(module);
return objectMapper;
}
使用的配置:
swagger-codegen-cli-3.0.14.jar -l java --library resttemplate
config.json“ dateLibrary”:“ java8”中的选项(创建OffsetDateTime 在客户代码中)
Maven依赖项:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
另请参阅:
答案 1 :(得分:0)
一个简单的答案是编写一个类,该类将是您的REST服务的返回值,如下所示:
public class MyDto {
ZonedDateTime time = ZonedDateTime.now();
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
public ZonedDateTime getTime() {
return time;
}
有关此问题的详细信息,请参见:Spring Data JPA - ZonedDateTime format for json serialization