问题
I am struggling with this issue for days now and have no clue how to solve this. Any quick help will be grateful. I need to convert LocalDate from JSON string which I am receiving from REST service build using apache CXF and jackson. I wrote custom ContextResolver and registered JavaTimeModule in Mapper object. When I run the application, default constructor is called, that means it has been loaded, but getContext() method which returns ObjectMapper never gets called.
I have registered same ContextResolver in server and client side. All dependencies are in place(jackson databind, core, annotation, datatype-jsr310).
I am able to fetch JSON response when I hit REST URI directly in browser. Issue comes when I call same URI annotated method from client code Below is my client code.
import javax.ws.rs.ext.ContextResolver;
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;
@Provider //makes this bean a Provider
public class LocalDateObjectMapperContextResolver implements ContextResolver<ObjectMapper>{
private final ObjectMapper MAPPER;
public LocalDateObjectMapperContextResolver() {
MAPPER = new ObjectMapper();
MAPPER.registerModule(new JavaTimeModule());
MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return MAPPER;
}
}
<jaxrs:client id="testclient"
serviceClass="package1.RESTService"
username="abc"
password="abc"
address="$serviceURL">
<jaxrs:features>
<bean class="org.apache.cxf.transport.common.gzip.GZIPFeature"/>
<cxf:logging/>
</jaxrs:features>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
<bean class="mypackage.LocalDateObjectMapperContextResolver"/>
</jaxrs:providers>
</jaxrs:client>
Same way, This contextResolver is registered on server side also under
<jaxrs:server>
.....
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
<bean class="mypackage.LocalDateObjectMapperContextResolver"/>
</jaxrs:providers>
</jaxrs:server>
Any reason why getContext is not called?
I also tried by extending ObjectMapper and registering javaTimeModule there, but dont know how to register customObjectMapper in Jackson flow. I just put default constructor for testing, And it does get called while application startup, but then again, No results, I still get same error.
Error: No suitable constructor found for type [simple type, class java.time.LocalDate]: can not instantiate from JSON object (need to add/enable type information?)
回答1:
I had exactly the same problem @peeskillet describes in question comment.
I was using Jackson dependencies from version 2 and jackson-jaxrs from version 1.
All solved when moved all dependencies to version 2.
回答2:
If you are using Maven you can add following two maven dependency.
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
And Add following code snippet.
@Configuration
public class CxfConfig {
@Component
@javax.ws.rs.ext.Provider
public static class JacksonJaxbJsonProvider
extends com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider {
@Autowired
private ObjectMapper objectMapper;
@PostConstruct
public void init() {
objectMapper.registerModule(new Jdk8Module());
}
}
}
来源:https://stackoverflow.com/questions/38168507/getcontext-method-of-customcontextresolver-is-not-called-by-jackson