I have written a custom JsonDeserializer
which contains an autowired service, as follows:
public class PersonDeserializer extends JsonDeserializ
As suggested in this comment and found on this link you need to create custom HandlerInstantiator:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
@Component
public class SpringBeanHandlerInstantiator extends HandlerInstantiator {
private ApplicationContext applicationContext;
@Autowired
public SpringBeanHandlerInstantiator(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public JsonDeserializer> deserializerInstance(DeserializationConfig config,
Annotated annotated,
Class> deserClass) {
try {
return (JsonDeserializer>) applicationContext.getBean(deserClass);
} catch (Exception e) {
// Return null and let the default behavior happen
}
return null;
}
@Override
public KeyDeserializer keyDeserializerInstance(DeserializationConfig config,
Annotated annotated,
Class> keyDeserClass) {
try {
return (KeyDeserializer) applicationContext.getBean(keyDeserClass);
} catch (Exception e) {
// Return null and let the default behavior happen
}
return null;
}
@Override
public JsonSerializer> serializerInstance(SerializationConfig config, Annotated annotated, Class> serClass) {
try {
return (JsonSerializer>) applicationContext.getBean(serClass);
} catch (Exception e) {
// Return null and let the default behavior happen
}
return null;
}
@Override
public TypeResolverBuilder> typeResolverBuilderInstance(MapperConfig> config, Annotated annotated,
Class> builderClass) {
try {
return (TypeResolverBuilder>) applicationContext.getBean(builderClass);
} catch (Exception e) {
// Return null and let the default behavior happen
}
return null;
}
@Override
public TypeIdResolver typeIdResolverInstance(MapperConfig> config, Annotated annotated, Class> resolverClass) {
try {
return (TypeIdResolver) applicationContext.getBean(resolverClass);
} catch (Exception e) {
// Return null and let the default behavior happen
}
return null;
}
}
Custom ObjectMapper:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
public class CustomObjectMapper extends ObjectMapper {
private static final long serialVersionUID = -8865944893878900100L;
@Autowired
ApplicationContext applicationContext;
public JamaxObjectMapper() {
// Problems serializing Hibernate lazily initialized collections? Fix here.
// HibernateModule hm = new HibernateModule();
// hm.configure(com.fasterxml.jackson.module.hibernate.HibernateModule.Feature.FORCE_LAZY_LOADING, true);
// this.registerModule(hm);
// Jackson confused by what to set or by extra properties? Fix it.
this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
}
@Override
@Autowired
public Object setHandlerInstantiator(HandlerInstantiator hi) {
return super.setHandlerInstantiator(hi);
}
}
and register your custom ObjectMapper:
At this moment you can use:
@JsonDeserialize(contentUsing=PersonDeserializer.class)
public void setPerson(Person person) {
...
}
... and personService will not be null.