【问题标题】:Two instances of ObjectMapperObjectMapper 的两个实例
【发布时间】:2020-02-13 12:55:33
【问题描述】:

有没有办法为不同的目的创建两个 ObjectMapper 实例。

修改后的 ObjectMapper

    @Component
    class MyObjectMapper extends ObjectMapper{
      public MyObjectMapper(){
        super();
      }

    public MyObjectMapper(MyObjectMapper om) {
        super(om);
     }

    @Override
    public MyObjectMapper copy() {
        return new MyObjectMapper(this);
     }
   }

现在按如下方式使用

@Autowired ObjectMapper objectMapper; //performs standard serialization
@Autowire MyObjectMapper myMapper; //i can add custom filters in thiis mapper.

我尝试了类似的设置,但自定义映射器实际上会影响原始映射器所有 rest controllers 抛出 JSON parse error: Unrecognized field

编辑:不确定这一点是否非常重要,但仍在添加 我正在使用spring-boot-starter-json

【问题讨论】:

  • 自定义映射器实际上会影响原始映射器”您实际上定义了两个 ObjectMapper 组件,还是 sn-p 的映射器是您拥有的唯一组件?
  • Mapper 是我唯一拥有的组件。原因是,将过滤器添加到 Autowired ObjectMapper 会永久应用更改。但我只需要在某些地方进行特殊的序列化。我可以在需要时做一个“新”,但我正在寻找一些干净的东西
  • 我不明白你在说什么。据我所知,如果这是您与ObjectMapper 相关的唯一配置,那么@Autowired ObjectMapper@Autowired MyObjectMapper 是完全相同的bean。您需要声明两个组件 bean:一个用于“干净”映射器,另一个 bean 用于自定义映射器。由于他们都是自动接线候选人,因此您需要对两者都进行资格认证并声明您要尝试自动接线(或对其中一个进行初步处理)。就像您在回答中所做的那样。
  • @Prokhorov 首先,MyObjectMapper 和 ObjectMapper 不是完全相同的 bean。使它相同的是你正在调用的'new ObjectMapper()',这是因为,我使用了一个自动的'Spring Boot Starter Json'。如果你使用标准的杰克逊和'@Bean',这可能会变得不那么模棱两可自己。

标签: java json spring-boot jackson objectmapper


【解决方案1】:

好的。结合Aniket 的回答,找出了问题所在,仍在寻找更多解释。

而不是将 ObjectMapper 实例化为 new ObjectMapper()。使用Mapper 构建它已修复它。

所以,两个有多个 ObjectMapper 实例

@Primary
@Bean
public ObjectMapper objectMapper(){
   return new Jackson2ObjectMapperBuilder()
                .build();
}

@Bean("customMapper")
public ObjectMapper customMapper(){
  ObjectMapper customMapper = new Jackson2ObjectMapperBuilder().build();
     mapper.<your customization , filters, providers etc;>
     return mapper;
}

@Primary 将在所有默认情况下使用,即当您只是 @Autowire 或控制器应用到您的响应/请求正文的默认序列化时。

要使用您的自定义映射器,请明确使用 Bean ID。

@Autowired @Qualifier("customMapper") ObjectMapper mapper;

【讨论】:

  • 这不正是上述答案中所建议的吗?此外,如果您将ObjectMapper 注入为ObjectMapper objectMapper,则不需要@Primary
  • @Somebody 阅读该答案中的所有 cmets。
  • 如果你使用'spring-boot-starter-json',@Primary 是强制性的
【解决方案2】:

这正是你应该使用@Qualifier注解的地方。

这个注解可以用在字段或参数上,作为自动装配时候选 bean 的限定符。它还可以用于注释其他自定义注释,然后这些注释又可以用作限定符。

【讨论】:

  • 现在这实际上质疑我的春季知识。 spring 是否将 MyCustomMapper 和 ObjectMapper 视为同一个 bean?为什么它会影响我的整体序列化? . MyCustomMapper 可能会扩展 ObjectMapper,同时它可以实现其他接口,将其作为单独的 bean 一起限定
  • Here is an example 我怀疑你的情况是错误的。首先运行程序按原样,然后取消注释它所写的部分取消注释下面并再次运行。为了对其进行更多控制,我建议使用Qualifier。毕竟这是你的选择:)
  • 尝试过的限定符。声明了两个 bean,一个为“@Primary”,一个为 Bean ID。并将修改后的 ObjectMapper 与“@Qualifier”一起使用。再一次,它弄乱了 Spring 用于所有控制器的实际隐式杰克逊。在配置中注释修改后的“@bean”可以解决问题
  • 您分享的示例不起作用。只是扩展 ObjectMapper 会抛出 'does not override copy()' 错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
相关资源
最近更新 更多