Deserialize LocalDateTime from String with Jackson - java

I'm trying to deserialize a String to LocalDateTime with Jackson but it doesn't work.
I have a data class with a LocalDateTime field:
#Data
public class Registration {
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
private LocalDateTime timestamp;
}
I added the special Jackson datatype modules:
compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
The serialization works fine with:
new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsString(registration);
Result String:
{"timestamp":"2018-09-03 10:09:35"}
But the deserialization doesn't work with:
new ObjectMapper().registerModule(new JavaTimeModule()).readValue(json.traverse(), Registration.class)
As error I get:
Cannot deserialize value of type `java.time.LocalDateTime` from String "2018-09-03 10:09:35":
Failed to deserialize java.time.LocalDateTime:
(java.time.format.DateTimeParseException) Text '2018-09-03 10:09:35' could not be parsed:
Unable to obtain LocalDateTime from TemporalAccessor:
{MinuteOfHour=9, NanoOfSecond=0, SecondOfMinute=35, MicroOfSecond=0, MilliOfSecond=0, HourOfAmPm=10},
ISO resolved to 2018-09-03 of type java.time.format.Parsed
What am I missing? I'm confused that the serialization works but the deserialization doesn't.
MWE: (small gradle Java project)
Main.java:
import java.io.IOException;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
public class Main {
public static void main(String[] args) throws IOException {
Registration registration = new Registration();
registration.setTimestamp(LocalDateTime.now());
ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
String s = objectMapper.writeValueAsString(registration);
TreeNode treeNode = objectMapper.readTree(s);
//Fails here:
Registration registration1 = objectMapper.readValue(treeNode.traverse(), Registration.class);
System.out.println(registration1);
}
}
class Registration {
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
private LocalDateTime timestamp;
public Registration() {
}
public LocalDateTime getTimestamp() {
return this.timestamp;
}
public void setTimestamp(LocalDateTime localDateTime) {
this.timestamp = localDateTime;
}
}
build.gradle:
plugins {
id 'java'
}
group 'dateMWE'
version '1.0-SNAPSHOT'
sourceCompatibility = 10
repositories {
mavenCentral()
}
dependencies {
compile("com.fasterxml.jackson.core:jackson-annotations:2.9.6")
compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.6")
}

The problem is not related with JSON deserialization, but rather with the time format string:
pattern = "yyyy-MM-dd hh:mm:ss"
Please notice that the hours are set as hh: this is a 12-hour formatter, which requires "AM" or "PM" values.
If the pattern is changed to
pattern = "yyyy-MM-dd HH:mm:ss"
the problem should be solved.

Your ObjectMapper is not managed by spring since you are creating object with new. Configure ObjectMapper as Bean in your configuration file. You need to register the DateTimeFormat with your LocalDateTimeDeserializer. Then set your Deserializer in JavaTimeModule.
#Bean
public ObjectMapper objectMapper() {
JavaTimeModule module = new JavaTimeModule();
LocalDateTimeDeserializer localDateTimeDeserializer = new
LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
ObjectMapper objectMapperObj = Jackson2ObjectMapperBuilder.json()
.modules(module)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.build();
return objectMapperObj;
}
Set the above configuration in your Spring configuration.

Related

How can i convert time from milis to date with time?

I have a class:
public class Test{
private String name;
private ZonedDateTime date1;
private ZonedDateTime date2;
and i also have a method to represent object in JSON format:
private String convertTestToJson(Test test) {
ObjectMapper mapper = new ObjectMapper();
try {
mapper.registerModule(new JavaTimeModule());
return mapper.writeValueAsString(test);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
When i creating the object i try to sout result in the console i got rightly json format with rigtly fields but time is represent in miliseconds :
{"reportType":"Test name","date1":1615978661.832223700,"date2":1615978661.837225400}
But i want to get date in normal format like year-month-day hour-minute-second-milis but when i remove this line: mapper.registerModule(new JavaTimeModule()); I got the exception:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.ZonedDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276)
at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4487)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3742)
at com.mycroft.report.Report.convertReportToJson(Test.java:38)
at com.mycroft.report.Report.generateReport(Test.java:30)
at com.mycroft.Main.main(Main.java:21)
I also got in dependency :
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.12.2</version>
</dependency>
And the question is how i can represent date in right format, no in miliseconds?
Change your class as follows:
public class Test{
private String name;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
private ZonedDateTime date1;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
private ZonedDateTime date2;
This should resolve your problem.
Source: Spring Data JPA - ZonedDateTime format for json serialization

Throw exception if a json input from FormDataBodyPart/Jackson if a date doesn't contain a timezone

Let's say I have a POST request with attachment in using Jersey Framework.
From my Jersey endpoint, i get a FormDataBodyPart, which contains that json string:
{
"aField": "aValue",
"aSecondField":"anotherValue",
"collectionDate" : {
"firstDate" : "2019-07-15",
"secondDate" : "2019-07-15T00:00:00.000Z"
}
}
When I deserialize that json into a Java Object, the firstDate field reflect another date because it didnt have a timezone (2019-07-14T22:00:00.000Z).
formDataBodyPartData.setMediaType(MediaType.APPLICATION_JSON_TYPE);
EntityExample entityExample = formDataBodyPartData.getValueAs(EntityExample.class);
So I'd like to force users to put the timezone information in each date.
Is it possible ? (I can have a solution based on Jackson too).
Thanks in advance.
EDIT :
The collectionDate class has the following schema and unfortunately I can't change it.
public class CollectionDate{
private java.util.Date firstDate;
private java.util.Date secondDate;
....
}
So I'd like a solution in order to restrict the unmarschalling of the json string when i use that line :
formDataBodyPartData.getValueAs(..)
I can have as well a solution based on Jackson, for instance :
EntityExample entityExample = objectMapper.readValue(value, EntityExample.class);
Thanks in advance.
You could use OffsetDateTime for mapping both firstDate and secondDate properties. The deserialization will fail when the input doesn't match the DateTimeFormatter.ISO_OFFSET_DATE_TIME pattern:
#Data
public class CollectionDate {
private OffsetDateTime firstDate;
private OffsetDateTime secondDate;
}
To use Jackson as JSON provider for JAX-RS, you must add the jackson-jaxrs-json-provider artifact as dependency.
And you will also need to register the JavaTimeModule in the ObjectMapper. It can be done in a ContextResolver<T>:
#Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperContextResolver() {
this.mapper = createObjectMapper();
}
#Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
private ObjectMapper createObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
return mapper;
}
}
Create a custom deserializer is the main solution but it doesnt fit to my project.
Anyway, this solution works :
Create a custom deserializer like below :
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public final class FlexDateDeserialiser extends JsonDeserializer<Date> {
#Override
public Date deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
final String date = parser.getText();
try {
return formatter.parse(date);
} catch (final ParseException ex) {
throw new IOException("Exemple date");
}
}
}
https://www.baeldung.com/jackson-serialize-dates
http://www.leveluplunch.com/java/tutorials/033-custom-jackson-date-deserializer/
We can use that custom deserializer directly in the POJO :
public class CollectionDate{
#JsonDeserialize(using = FlexDateDeserialiser.class) private java.util.Date firstDate;
#JsonDeserialize(using = FlexDateDeserialiser.class) private java.util.Date secondDate;
....
}

custom deserializing a date with format

["last_modified"])] with root cause
java.time.format.DateTimeParseException: Text '2018-06-06T13:19:53+00:00' could not be parsed, unparsed text found at index 19
The inbound format is 2018-06-06T13:19:53+00:00
It's a weird format.
I have tried the following:
public class XYZ {
#DateTimeFormat(pattern = "yyyy-MM-ddTHH:mm:ss+00:00", iso = ISO.DATE_TIME)
private LocalDateTime lastModified;
}
There is nothing stopping you from creating your own deserializer. A very naive example could be the following:
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
private static final String PATTERN = "yyyy-MM-dd'T'HH:mm:ss+00:00";
private final DateTimeFormatter formatter;
public LocalDateTimeDeserializer() {
this.formatter = DateTimeFormatter.ofPattern(PATTERN);
}
#Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return LocalDateTime.parse(p.getText(), formatter);
}
}
The only thing you need to notice is that you'll need to escape the 'T' by adding single quote around it.
With the deserializer in place you can simply annotate the field like so:
#JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime dateTime;
The inbound format is 2018-06-06T13:19:53+00:00
It's a weird format.
That's the ISO 8601 format, which is endorsed by the RFC 3339 and by the xkcd 1179:
The following should work as expected when receiving the values as query parameters:
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDate dateTime;
As 2018-06-06T13:19:53+00:00 represents a date and time with an offset from UTC, you'd better use OffsetDateTime rather than LocalDateTime:
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private OffsetDateTime dateTime;
Just ensure that + is encoded as %2B.
With Jackson, you could add the jackson-datatype-jsr310 dependency to your application. This module will provide you with serializers and deserializers for java.time types.
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
And then register the JavaTimeModule module in your ObjectMapper:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
Jackson will handle the serialization and deserialization for you.
If you are, for some reason, not interested in the offset from UTC and want to keep using LocalDateTime, you could extend the LocalDateTimeDeserializer provided by Jackson and use a custom DateTimeFormatter:
public class CustomLocalDateTimeDeserializer extends LocalDateTimeDeserializer {
public CustomLocalDateTimeDeserializer() {
super(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
}
Then annotate the LocalDateTime field as shown below:
#JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
private LocalDateTime dateTime;
The inbound format is 2018-06-06T13:19:53+00:00
If you're able to set the Date Format on your entire ObjectMapper, you could do the following:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
objectMapper.setDateFormat(df);
This is part of the examples from the SimpleDateFormat Javadocs

Jackson , java.time , ISO 8601 , serialize without milliseconds

I'm using Jackson 2.8 and need to communicate with an API that doesn't allow milliseconds within ISO 8601 timestamps.
The expected format is this: "2016-12-24T00:00:00Z"
I'm using Jackson's JavaTimeModule with WRITE_DATES_AS_TIMESTAMPS set to false.
But this will print milliseconds.
So I tried to use objectMapper.setDateFormat which didn't change anything.
My current workaround is this:
ObjectMapper om = new ObjectMapper();
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendInstant(0)
.toFormatter();
JavaTimeModule jtm = new JavaTimeModule();
jtm.addSerializer(Instant.class, new JsonSerializer<Instant>() {
#Override
public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeString(dtf.format(value));
}
});
om.registerModule(jtm);
I'm overriding the default serializer for Instant.class which works.
Is there any nice way using some configuration parameter to solve this?
Update:
Just add a #JsonFormat annotation with the date format above the Instant property. It's very easy.
In the case you have an ObjectMapper with the JavaTimeModule like next:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
If you have a class with an Instant property, you should add the #JsonFormat annotation and put the date pattern which hasn't milliseconds. It would be like next:
public static class TestDate {
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss", timezone = "UTC")
Instant instant;
//getters & setters
}
So if you serialize an object to Json it works perfectly:
String json = mapper.writeValueAsString(testDate);
System.out.println(json);
Output
{"instant":"2016-11-10 06:03:06"}
Old Answer. I don't know why but It doesn't work properly:
You could use the Jackson2ObjectMapperBuilder to build it.
You just need to add the dateFormat you want. It would be something like next:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
ObjectMapper mapper = Jackson2ObjectMapperBuilder
.json()
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.modules(new JavaTimeModule())
.dateFormat(dateFormat)
.build();
Here is an alternative which is something you can set globally, but will need you to use ZonedDateTime with instant formatter as we can't set the format for the Instant Serializer provided with Java Time Module.
You wont see any side effects of using zoned date time for instant as jackson serializes the zone id separately and is disabled by default. So technically, this is similar to applying the formatter to Instant.
When used this way, the ZonedDateTime serializer delegates the serialization to InstantBaseSerializer and uses the specified custom format.
#RunWith(JUnit4.class)
public class InstantNoMillisTest {
private ObjectMapper objectMapper;
#Before
public void init() {
JavaTimeModule module = new JavaTimeModule();
ZonedDateTimeSerializer zonedDateTimeSerializer = new ZonedDateTimeSerializer(new DateTimeFormatterBuilder().appendInstant(0).toFormatter());
module.addSerializer(ZonedDateTime.class, zonedDateTimeSerializer);
module.addDeserializer(ZonedDateTime.class, InstantDeserializer.ZONED_DATE_TIME);
objectMapper = Jackson2ObjectMapperBuilder.json()
.modules(module)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.build();
}
#Test
public void serialize() throws IOException {
ZonedDateTime zonedDateTime = ZonedDateTime.now();
String noMillis = objectMapper.writeValueAsString(zonedDateTime);
System.out.print(noMillis);
}
#Test
public void deserialize() throws IOException {
String dateTime = "\"2017-10-26T12:54:59Z\"";
ZonedDateTime noMillis = objectMapper.readValue(dateTime, ZonedDateTime.class);
System.out.print(noMillis);
}
}
Here's some Kotlin code of formatting Instant fields, so they will not contain milliseconds, you can use custom date formatters
ObjectMapper().apply {
val javaTimeModule = JavaTimeModule()
javaTimeModule.addSerializer(Instant::class.java, Iso8601WithoutMillisInstantSerializer())
registerModule(javaTimeModule)
disable(WRITE_DATES_AS_TIMESTAMPS)
}
private class Iso8601WithoutMillisInstantSerializer
: InstantSerializer(InstantSerializer.INSTANCE, false, DateTimeFormatterBuilder().appendInstant(0).toFormatter())

Jersey parsing Java 8 date time

This is my user class, and I to save ISO compliant date time in my database.
public class User {
#Id
private String id;
private String email;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime loginDate;
}
Here is my Jersey controller:
#POST
#Consumes("application/json")
#Produces("application/json")
public Response create( User user) {
Map<Object, Object> apiResponse = new HashMap<Object, Object>();
Map<Object, Object> response = new HashMap<Object, Object>();
user = (User) userService.create(user);
}
How can can I consume a datetime format like this one in jersey? Is it possible to send a datatime String and create Java 8 date time object automatically?
{
"email" : "imz.mrz#gmail.com"
"loginDate" : "2015-04-17T06:06:51.465Z"
}
#
Update:
I was using Spring boot jersey, and had other jsr packages
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
So I removed all the packages except from spring-boot-jersey package.
use this annotation for LocalDateTime
#JsonDeserialize(using = LocalDateTimeDeserializer.class)
This way I can consume ISODate and save ISODate() to mongodb and produce full formated mongodb LocalDateTime to frontend.
Problem solved.
Couple options I see...
Option 1:
Assuming you have JAXB annotation support with Jackson as the JSON provider...
You could use an XmlAdapter. For example
public class LocalDateTimeAdapter extends XmlAdapter<String, LocalDateTime> {
#Override
public LocalDateTime unmarshal(String dateString) throws Exception {
Instant instant = Instant.parse(dateString);
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return dateTime;
}
#Override
public String marshal(LocalDateTime dateTime) throws Exception {
Instant instant = dateTime.toInstant(ZoneOffset.UTC);
return DateTimeFormatter.ISO_INSTANT.format(instant);
}
}
See the Instant API for more information.
Then you can just annotate the field/property with the adapter
#XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
private LocalDateTime loginDate;
You could also declare the annotation at the package level, so that all uses in the package will use the adapter, without the need to annotate. You do so in a file named package-info.java put inside the package
#XmlJavaTypeAdapters({
#XmlJavaTypeAdapter(type = LocalDateTime.class,
value = LocalDateTimeAdapter.class)
})
package thepackage.of.the.models;
import java.time.LocalDateTime;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
Option 2:
Use the Jackson APIs directly. Meaning, use a JsonDeserializer and JsonSerializer. For example
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
#Override
public LocalDateTime deserialize(JsonParser jp,
DeserializationContext dc) throws IOException, JsonProcessingException {
ObjectCodec codec = jp.getCodec();
TextNode node = (TextNode)codec.readTree(jp);
String dateString = node.textValue();
Instant instant = Instant.parse(dateString);
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return dateTime;
}
}
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
#Override
public void serialize(LocalDateTime dateTime, JsonGenerator jg,
SerializerProvider sp) throws IOException, JsonProcessingException {
Instant instant = dateTime.toInstant(ZoneOffset.UTC);
jg.writeString(DateTimeFormatter.ISO_INSTANT.format(instant));
}
}
You can apply this at the field/property level
#JsonSerialize(using = LocalDateTimeSerializer.class)
#JsonDeserialize(using = LocalDateTimeDeserializer.class)
public LocalDateTime loginDate;
Or at the ObjectMapper level (so you don't need to annotate everywhere)
#Provider
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
final ObjectMapper mapper = new ObjectMapper();
public ObjectMapperContextResolver() {
SimpleModule module = new SimpleModule();
module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
mapper.registerModule(module);
// add JAXB annotation support if required
mapper.registerModule(new JaxbAnnotationModule());
}
#Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
Basically what happens, is that the MessageBodyWriter/MessageBodyReader used for ummarshalling/marshalling, will call the getContext method to get the ObjectMapper
Note:
The above solutions will parse from the format 2007-12-03T10:15:30.00Z, as documented in Instant.parse, and will serialize to the same format, as documented in DateTimeFormatter.ISO_INSTANT
The above is also assuming you are using Jackson as the Serializer. I used the below dependency (with Jersey 2.16) to test
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>
The dependency uses a JacksonJaxbJsonProvider for JAXB annotation support. If you are using a lower version of Jersey like 1.x, the jersey-json dependency should offer JAXB annotation support, if you enable the POJO mapping feature. Alternatively for Jersey 1.x, if you want to use Jackson 2, you can use this dependency
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.4.0</version>
</dependency>
which is actually what is used by jersey-media-json-jackson. So you could explicitly register the JacksonJaxbJsonProvider, or add the Jackson package (com.fasterxml.jackson.jaxrs.json) to list packages to scan
UPDATE
See Also:
Java 8 LocalDate Jackson format. There is Jackson Module that already comes with serializers for the Java 8 date/time APIs.

Categories