【问题标题】:Using different jackson ObjectMappers for seperate RequestMapping使用不同的杰克逊 ObjectMapper 进行单独的 RequestMapping
【发布时间】:2017-12-22 15:00:26
【问题描述】:

我有一个使用自定义 MIME 类型的 @RequestMapping。该请求使用@Configuration 中定义的ObjectMapper bean 来启用JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER

此功能允许使用通常无效的 json(将反斜杠视为非特殊字符),这是此特定 @RequestMapping 的要求,以允许直接解析 google 编码的折线。然而,这意味着这个 ObjectMapper 现在被用于我的@RequestMapping所有,而实际上它只是一个要求。

有没有办法区分每个 @Controller@RequestMapping 使用的 ObjectMapper?

对象映射器 Bean

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

    return builder.build();
}

请求映射接口方法

@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);

【问题讨论】:

  • 您想要只对 Journey 界面进行自定义处理吗?
  • @lexknuther 基本上是的。
  • 另外,您使用的是什么版本的 Jackson?
  • 在这里您可以找到解决问题的可能方法 - stackoverflow.com/questions/42691392/…
  • @lexknuther 2.6.6

标签: java spring spring-boot jackson objectmapper


【解决方案1】:

我在另一个用户链接到我的另一个 stackoverflow 问题中找到了答案 - https://stackoverflow.com/a/45157169/2073800

我只需将以下@Bean 添加到我的@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);
}

【讨论】:

    【解决方案2】:

    如果您有一个自定义 MIME 类型,那么您可以注册一个自定义 HttpMessageConverter,它为您的 MIME 类型使用特殊的 ObjectMapper,并从 canRead/canWrite 中返回 false 用于常规 MIME 类型。您像这样注册您的自定义HttpMessageConverter

    @EnableWebMvc
    @Configuration
    @ComponentScan
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void configureMessageConverters(
          List<HttpMessageConverter<?>> converters) {
    
            messageConverters.add(myCustomMessageConverter());
    
            super.configureMessageConverters(converters);
        }
    }
    

    将其视为与内容协商有关,与 URL 映射无关; URL 映射 (@RequestMapping) 用于查找处理程序,而不是用于选择要使用的编组器/解组器。

    【讨论】:

    • 理解内容协商和对我的问题的评论为我指明了正确的方向。我不怀疑上述解决方案会奏效,但我发现了一些更简单的方法。
    • @Jags 我查看了 Szymon Stepniak 在另一个线程中的内容,它与我所说的完全相似,除了您如何注册转换器的部分。当您说您不怀疑上述方法会起作用时,我怀疑您并不真正了解发生了什么。
    • 我不同意你的答案是相似的,但是他的答案更容易理解和更好地解释。我也同意我可能不完全理解其中的复杂性,但也许这也反映了您的答案质量?我应用了您的答案,据我了解,我创建了HttpMessageConverter 的自定义实现,并覆盖了仅接受一个MediaType 的方法。 Szymons 的回答更加简洁明了。
    猜你喜欢
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 2021-01-23
    • 2020-05-24
    • 1970-01-01
    相关资源
    最近更新 更多