Search code examples
javaspringspring-bootjacksonobjectmapper

Using different jackson ObjectMappers for seperate RequestMapping


I have a single @RequestMapping that consumes a custom MIME type. The request uses an ObjectMapper bean defined in the @Configuration to enabled the JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.

This feature allows typically invalid json (treating backslashes as a non-special character) to be consumed, which is a requirement of this particular @RequestMapping to allow google encoded polylines to be parsed directly. However this means that this ObjectMapper is now being used for ALL of my @RequestMapping when it is really only a requirement for one.

Is there a way to differentiate the ObjectMapper being used for each @Controller or @RequestMapping?

Object Mapper Bean

@Bean
public ObjectMapper objectMapper() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.featuresToEnable(
      JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER);

    return builder.build();
}

Request Mapping Interface Method

@ApiOperation(value = "Returns the toll cost breakdown for a journey", notes = "", response = TotalCost.class, tags={ "pricing", })
@ApiResponses(value = { 
    @ApiResponse(code = 200, message = "successful operation", response = TotalCost.class) })
@RequestMapping(value = "/pricing/journeyCost",
    produces = { "application/json" }, 
    consumes = { "application/vnd.toll-pricing+json" },
    method = RequestMethod.POST)
ResponseEntity<TotalCost> getTollBreakdownFromEncodedPoly(@ApiParam(value = "Request object representing the journey" ,required=true ) @RequestBody Journey body);

Solution

  • I found the answer in another stackoverflow question linked to me by another user - https://stackoverflow.com/a/45157169/2073800

    I just had to add the following @Bean to my @Configuration

    @Bean
    public HttpMessageConverters customConverters() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.featuresToEnable(
          JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER);
    
        final AbstractJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(builder.build());
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.valueOf("application/vnd.toll-pricing+json")));
    
        return new HttpMessageConverters(converter);
    }