Issue
I tried all the solutions provided on these below SO threads:
Jackson FAIL_ON_UNKNOWN_PROPERTIES to false not working
Spring Boot Web- Set FAIL_ON_UNKNOWN_PROPERTIES to false in Jackson
And around 10 more similar SO threads.
Here is my Spring Boot application:
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class MyApplication {
@Autowired
private WebClient webClient;
public static void main(String args[]) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
public CommandLineRunner demo() {
return (args) -> {
getDetails("abcd12345");
};
}
private void getDetails(String nodeId) throws IOException {
Mono<String> mono = webClient.get().uri("/end/point").retrieve().bodyToMono(String.class);
System.out.println(mono.block());
final ObjectNode node = objectMapper().readValue(mono.block(), ObjectNode.class);
System.out.println(node.get("parent").get("properties").get("nonExisting:keyhere").asText()); // NPE here
}
@Bean
public ObjectMapper objectMapper() {
return Jackson2ObjectMapperBuilder.json().featuresToEnable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();
}
@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.failOnUnknownProperties(false);
return builder;
}
}
And my application.properties file has:
spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=false
Output:
Caused by: java.lang.NullPointerException: null
at com.springbatch.parallel.processing.Application.getDetails(MyApplication .java:43)
But still I am getting NullPointerException (NPE) for non-existing key. I am trying to disable FAIL_ON_UNKNOWN_PROPERTIES. What I am missing here?
Solution
You will need to cope with the possibility of null
being returned by any of the calls in that chained method call as follows:
private void getDetails(String nodeId) throws IOException {
Mono<String> mono = webClient.get().uri("/end/point").retrieve().bodyToMono(String.class);
System.out.println(mono.block());
final ObjectNode node = objectMapper().readValue(mono.block(), ObjectNode.class);
JsonNode parentNode = node.get("parent");
if (parentNode != null) {
JsonNode parentPropertiesNode = parentNode.get("properties");
if (parentPropertiesNode != null) {
JsonNode nonExistingKeyNode = parentPropertiesNode.get("nonExisting:keyhere");
if (nonExistingKeyNode != null) {
System.out.println(nonExistingKeyNode.asText());
}
}
}
}
Additionally, avoid at all costs using block()
in a Reactive stack. By doing this you are wasting all the benefits of using Spring WebFlux. Here is a very interesting online resource about common mistakes while using the Reactive stack: https://medium.com/javarevisited/five-mistakes-to-avoid-in-reactive-java-786927ffd2f6.
Answered By - João Dias