I am trying to autowire a component into a custom JsonDeserializer but cannot get it right even with the following suggestions I found:
- Autowiring in JsonDeserializer: SpringBeanAutowiringSupport vs HandlerInstantiator
- Right way to write JSON deserializer in Spring or extend it
- How to customise the Jackson JSON mapper implicitly used by Spring Boot?
- Spring Boot Autowiring of JsonDeserializer in Integration test
My final goal is to accept URLs to resources in different microservices and store only the ID of the resource locally. But I don't want to just extract the ID from the URL but also verify that the rest of the URL is correct.
I have tried many things and lost track a bit of what I tried but I believe I tried everything mentioned in the links above. I created tons of beans for SpringHandlerInstantiator, Jackson2ObjectMapperBuilder, MappingJackson2HttpMessageConverter, RestTemplate and others and also tried with setting the SpringHandlerInstantiator in RepositoryRestConfigurer#configureJacksonObjectMapper.
I am using Spring Boot 2.1.6.RELEASE which makes me think something might have changed since some of the linked threads are quite old.
Here's my last attempt:
@Configuration
public class JacksonConfig {
@Bean
public HandlerInstantiator handlerInstantiator(ApplicationContext applicationContext) {
return new SpringHandlerInstantiator(applicationContext.getAutowireCapableBeanFactory());
}
}
@Configuration
public class RestConfiguration implements RepositoryRestConfigurer {
@Autowired
private Validator validator;
@Autowired
private HandlerInstantiator handlerInstantiator;
@Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("beforeCreate", validator);
validatingListener.addValidator("beforeSave", validator);
}
@Override
public void configureJacksonObjectMapper(ObjectMapper objectMapper) {
objectMapper.setHandlerInstantiator(handlerInstantiator);
}
}
@Component
public class RestResourceURLSerializer extends JsonDeserializer<Long> {
@Autowired
private MyConfig config;
@Override
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ServiceConfig serviceConfig = config.getServices().get("identity");
URI serviceUri = serviceConfig.getExternalUrl();
String servicePath = serviceUri.getPath();
URL givenUrl = p.readValueAs(URL.class);
String givenPath = givenUrl.getPath();
if (servicePath.equals(givenPath)) {
return Long.parseLong(givenPath.substring(givenPath.lastIndexOf('/') + 1));
}
return null;
}
}
I keep getting a NullPointerException POSTing something to the API endpoint that is deserialized with the JsonDeserializer above.