rest - com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.LocalDateTime] from String -
i have java8 localdatetime in jax-rs rest apis. webapp deployed in wildfly10. when make post call(which includes localdatetime parameter) following exception;
caused by: com.fasterxml.jackson.databind.jsonmappingexception: can not instantiate value of type [simple type, class java.time.localdatetime] string value ('2016-06-02t00:08:25.605z'); no single-string constructor/factory method @ [source: io.undertow.servlet.spec.servletinputstreamimpl@396d1714; line: 2, column: 3] (through reference chain: com.leightonobrien.core.model.base.company["created"]) @ com.fasterxml.jackson.databind.jsonmappingexception.from(jsonmappingexception.java:148) @ com.fasterxml.jackson.databind.deserializationcontext.mappingexception(deserializationcontext.java:843) @ com.fasterxml.jackson.databind.deser.valueinstantiator._createfromstringfallbacks(valueinstantiator.java:277) @ com.fasterxml.jackson.databind.deser.std.stdvalueinstantiator.createfromstring(stdvalueinstantiator.java:284) @ com.fasterxml.jackson.databind.deser.beandeserializerbase.deserializefromstring(beandeserializerbase.java:1150) @ com.fasterxml.jackson.databind.deser.beandeserializer._deserializeother(beandeserializer.java:153) @ com.fasterxml.jackson.databind.deser.beandeserializer.deserialize(beandeserializer.java:144) @ com.fasterxml.jackson.databind.deser.settablebeanproperty.deserialize(settablebeanproperty.java:523) @ com.fasterxml.jackson.databind.deser.impl.fieldproperty.deserializeandset(fieldproperty.java:101) @ com.fasterxml.jackson.databind.deser.impl.beanpropertymap.finddeserializeandset(beanpropertymap.java:285) @ com.fasterxml.jackson.databind.deser.beandeserializer.vanilladeserialize(beandeserializer.java:248)
based on following guides ;
and
jaxrs not find custom (de)serializers joda.money type
and
https://github.com/fasterxml/jackson-datatype-jsr310
i have written provider , registered in application path;
package com.test; import java.lang.annotation.annotation; import java.lang.reflect.type; import java.time.localdatetime; import java.time.format.datetimeformatter; import javax.ws.rs.ext.paramconverter; import javax.ws.rs.ext.paramconverterprovider; import javax.ws.rs.ext.provider; import com.fasterxml.jackson.databind.objectmapper; import com.fasterxml.jackson.databind.serializationfeature; import com.fasterxml.jackson.datatype.jsr310.javatimemodule; import com.fasterxml.jackson.jaxrs.json.jacksonjsonprovider; @provider public class localdatetimeconverterprovider extends jacksonjsonprovider implements paramconverterprovider { private final localdatetimeconverter converter = new localdatetimeconverter(); @override public <t> paramconverter<t> getconverter(class<t> rawtype, type generictype, annotation[] annotations) { if (!rawtype.equals(localdatetime.class)) return null; return (paramconverter<t>) converter; } public class localdatetimeconverter implements paramconverter<localdatetime> { @override public localdatetime fromstring(string value) { datetimeformatter formatter = datetimeformatter.ofpattern("yyyy-mm-dd hh:mm"); localdatetime datetime = localdatetime.parse(value, formatter); return datetime; } @override public string tostring(localdatetime value) { datetimeformatter formatter = datetimeformatter.ofpattern("yyyy-mm-dd hh:mm"); string formatteddatetime = value.format(formatter); return formatteddatetime; } } public localdatetimeconverterprovider() { objectmapper mapper = new objectmapper(); mapper.disable(serializationfeature.write_dates_as_timestamps); mapper.registermodule(new javatimemodule()); setmapper(mapper); } } import javax.ws.rs.applicationpath; @applicationpath("/rest") public class restapplication extends application { @override public set<class<?>> getclasses() { hashset<class<?>> set = new hashset<class<?>>(); set.add(com.test.jsonmoneyprovider.class); set.add(com.test.durtaionconverterprovider.class); set.add(com.test.localdatetimeconverterprovider.class); set.add(com.test.moneyconverterprovider.class); ...
i make post call like;
curl -x post --header 'content-type: application/json' -d '{ "created": "2016-06-02t00:08:25.605z", "updated": "2016-06-02t00:08:25.605z", "id": 0, "code": "string", "name": "string", "abn": "string", "addresses": [ { "id": 0, "address1": "string", "address2": "string", "city": "string", "state": "string", "postcode": "string", "country": "string", "gps": { "latitude": { "latitude": 0, "value": 0 }, "longitude": { "longitude": 0, "value": 0 }' 'http://localhost:8080/test2dbwar/rest/companys'
how can overcome above issue? i'm clueless..i tried put stuff (try avoid wildfly's jax-rs complex support issue, jackson serialization issue) , sort out issue..
any help?
the first question linked involves conversion of @xxxparam
annotations. paramconverterprovider
for. different (de)serailization process entity body (de)serialization.
for entity (de)serialization, messagebodyreader/messagebodywriter
s used. jackson provides 1 such implementation, in jacksonjsonprovider/jacksonjaxbjsonprovider
, using, whether know or not. configuration localdatatime
needs somehow configured provider.
the way configure jackson support localdatetime
serialization, through it's objectmapper
. can create custom json(de)serializer
, mentioned in post (option two), or can use jsr310module
(that has custom json(de)serializer
localdatetime
), mentioned in this post.
to configure jacksonjsonprovider/jacksonjaxbjsonprovider
use configured objectmapper
, can use contextresolver
, mentioned in both of previous links, or can construct jacksonjsonprovider
objectmapper
, , register provider
objectmapper mapper = new objectmapper(); mapper..configurmoduleorserializer jacksonjsonprovider provider = new jacksonjsonprovider(mapper); registerprovier(provider)
personally go contextresolver
, mentioned in links. difference above code, objectmapper
provided provider explicitly, while contextresolver
, during runtime, provider search jax-rs registry contextresolver
of type objectmapper
, , obtain way.