问题
I am building a REST webservice. Some classes have an attribute of type DateTime
(JodaTime).
When sending this object to my client (Javascript), my object
private DateTime date;
is transformed to
{ date: { chronology: {}, millis: 1487289600000 } }
The problem is that I have an error when sending this object back to the server because I cannot instantiate chronology
I would like to have something like { date: 1487289600000}
- Any other format could work.
Environment
- jackson-annotations 2.8.8
- jackson-core 2.8.8
- jackson-databin 2.8.8
- jackson-datatype-joda 2.8.8
- joda-time 2.7
My context resolver is
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
final ObjectMapper mapper = new ObjectMapper();
public ObjectMapperContextResolver() {
mapper.registerModule(new JodaModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
What am I missing ? If I am not using ObjectMapperContextResolver
I have the same result
Update following @Cássio Mazzochi Molin's answer
I added jackson-jaxrs-json-provider 2.8.8
, jackson-jaxrs-base 2.8.8
and jackson-module-jaxb-annotations 2.8.8
My context resolver is now like this
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
final ObjectMapper mapper = new ObjectMapper();
public ObjectMapperContextResolver() {
mapper.registerModule(new JodaModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
And my application config
@javax.ws.rs.ApplicationPath("/")
public class ApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<>();
resources.add(AuthenticationFilter.class);
resources.add(CORSFilter.class);
resources.add(ObjectMapperContextResolver.class);
resources.add(JacksonJsonProvider.class);
resources.add(ServiceResource.class);
return resources;
}
}
My serviceResource
@Path("service")
public class ServiceResource {
@Path("/forecast/stocks/{modelId}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Value> getStocks(@PathParam("modelId") String modelId, @QueryParam("startDate") String startDate, @QueryParam("endDate") String endDate) {
try {
DateTime datetimeStart = formatStringToDatetime(startDate);
DateTime datetimeEnd = formatStringToDatetime(endDate);
return logicClass.getStocks(modelId, datetimeStart, datetimeEnd);
} catch (Exception e) {
logger.log(Level.SEVERE, "Error calling /hydromax/forecast/stocks", e);
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
}
And the Value
object
public class Value {
private DateTime date;
private Float value;
public Value() {
}
//getter and setter
}
Update
I have added the following code inside ApplicationConfig
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("jersey.config.server.disableMoxyJson", true);
return props;
}
My DateTime
is now transformed to
"date":{"dayOfMonth":16,"dayOfWeek":4,"era":1,"year":2017,"dayOfYear":47,"weekOfWeekyear":7,"secondOfMinute":0,"millisOfSecond":0,"weekyear":2017,"monthOfYear":2,"hourOfDay":10,"minuteOfHour":0,"yearOfEra":2017,"yearOfCentury":17,"centuryOfEra":20,"millisOfDay":36000000,"secondOfDay":36000,"minuteOfDay":600,"millis":1487235600000,"zone":{"fixed":false,"uncachedZone":{"fixed":false,"cachable":true,"id":"Europe/Paris"},"id":"Europe/Paris"},"chronology":{"zone":{"fixed":false,"uncachedZone":{"fixed":false,"cachable":true,"id":"Europe/Paris"},"id":"Europe/Paris"}},"afterNow":false,"beforeNow":true,"equalNow":false}
And the first time I call the service after deployment, I have this error
javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.NoClassDefFoundError: com/fasterxml/jackson/module/jaxb/JaxbAnnotationIntrospector
回答1:
You are probably missing the jackson-jaxrs-json-provider module in your application.
This module is the Jackson JSON provider for JAX-RS implementations, such as Jersey and RESTeasy.
A ContextResolver for ObjectMapper is only required if you need to customize the ObjectMapper for the Jackson JSON provider. But the ContextResolver won't do anything if the Jackson provider is not registered.
Here's the dependency you need:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.8.8</version>
</dependency>
If you are not using Maven, add jackson-jaxrs-json-provider-2.8.8.jar to the classpath.
Then register JacksonJsonProvider (using only Jackson annotations) or JacksonJaxbJsonProvider (using both Jackson and JAXB annotations), according to your needs.
来源:https://stackoverflow.com/questions/44652189/deserialize-datetime-joda-with-jackson