Problem: When our REST service returns objects with date/datetime fields, these fields are encoded as complex structures in the JSON format:
...
"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
},
...
I want these temporal data types to be serialized to string in a simple format like "2017-10-05T16:05:25".
The project was originally based on Java 7 API and java.util.Date
was used everywhere – and it worked. When I switched to Java 8 and started using the new java.time
classes, everything worked except for the serialization of the date/time objects to JSON.
I know I could revert to using the java.util.Date
type again but I would prefer using the new data types.
The REST service is defined using Swagger and built with Maven. The swagger-codegen-maven-plugin
is used, with the following configuration:
jaxrs-cxf-cdi
java8
Here are versions of other related libraries (as defined in the POM):
swagger-codegen
: 2.2.3cxf-bundle-jaxrs
: 2.7.18gson
: 2.8.1I'm quite new to REST services (I've only worked with SOAP services until recently).
I've tried to find a way of customizing the output of serialization to JSON but didn't succeed. I found out that OffsetDateTime
should be a supported type (regarding serialization) and should be serialized nicely. I have also tried to configure the Maven plugin to use Java library 'java8-localdatetime' with type LocalDateTime
– but it didn't help – the serialized instance of LocalDateTime
was still converted as a complex JSON object.
Could you help me with this? Thanks.
I had the same issue today, my approach was to follow the dependencies starting with the generated 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;
}
Used configuration:
swagger-codegen-cli-3.0.14.jar -l java --library resttemplate
Options in config.json "dateLibrary":"java8" (creates OffsetDateTime in client code)
Maven Dependencies:
<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>
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With