Spring Boot 1.4 自定义内部 Jackson 反序列化

Posted

技术标签:

【中文标题】Spring Boot 1.4 自定义内部 Jackson 反序列化【英文标题】:Spring Boot 1.4 Customize Internal Jackson Deserialization 【发布时间】:2017-08-10 00:08:10 【问题描述】:

我在application.properties 中使用spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=true 使反序列化在未知属性上失败,但它不起作用。

我什至尝试过使用:

@Bean
ObjectMapper objectMapper() 
  return Jackson2ObjectMapperBuilder
        .json()
        .featuresToEnable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
        .build();

但这也没有用。我错过了什么?

【问题讨论】:

你能发布你的代码和你试图反序列化的对象的数据吗? 如果您在这个问题中定义Jackson2ObjectMapperBuilder 是否有效:***.com/questions/34545997/… ? @Infinity 感谢您的快速回复。我也试过了,但没有用这是一个简单的项目,它具有 spring-boot web 依赖项和一个更新用户的 PUT 请求方法(对,我没有访问数据库,我只是将更新请求记录到测试方法)和一个普通的没有任何附加注释的用户模型。 那么它是否适用于 POST 请求? @Infinity 不,它也不适用于 POST。 【参考方案1】:

使用 Spring boot,默认情况下,在反序列化过程中会忽略未知属性。 为了不忽略这些属性,您可以:

在application.properties中添加spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=true

使用这个 bean:

@Bean
public ObjectMapper objectMapper() 
    return Jackson2ObjectMapperBuilder
    .json()
    .featuresToEnable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
    .build();

使用这个 bean:

@Bean 
public Jackson2ObjectMapperBuilder objectMapperBuilder()
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.failOnUnknownProperties(true);
    return builder;

我已经测试了这些解决方案并且它可以工作,因此您的代码中存在另一个问题。 请问,你能按照javaguy的要求发布你的代码吗?

【讨论】:

感谢您的快速回复。它现在可以工作了,我清除了 m2 缓存并重建它,可能是版本问题。我稍后会检查是什么原因造成的。我无法将您和 Fırat 家伙的回复都标记为答案。但是感谢您的快速回复:)。 这个答案更完整,它提供了多种解决方案,在我的情况下(依赖于 Spring 的自动配置)Spring 正在实例化多个 ObjectMappers,其中只有一个使用了我设置的属性在application.properties。使用此答案中的第三个选项对我有用(尽管我必须为MappingJackson2HttpMessageConverter 添加一个@Bean,它使用我的自定义Jackson2ObjectMapperBuilder 才能工作)。【参考方案2】:

FAIL_ON_UNKNOWN_PROPERTIES选项根据Jackson Documentation默认为true。

如果您想禁用此设置,您可以将此选项添加到application.properties

spring.jackson.deserialization.fail-on-unknown-properties = false

但在默认设置下,它按预期工作。所以不需要任何设置。

这是一个文件spring boot应用:

@RestController
@SpringBootApplication
public class TestOptionApplication 

    public static void main(String[] args) 
        SpringApplication.run(TestOptionApplication.class, args);
    

    @PostMapping("/test")
    public void formTest(@RequestBody final HelloForm form) 
    

    public static class HelloForm 

        private String name;

        public String getName()  return name; 

        public void setName(final String name)  this.name = name; 
    

这是用于测试拒绝未知属性的集成测试。

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestOptionApplicationTest 

    @Autowired
    private WebApplicationContext context;

    @Test
    public void testFailOnUnknownPropertiesOption() throws Exception 

        final String text = "\"name\": \"test\", \"title\": \"test\"";

        MockMvcBuilders
            .webAppContextSetup(this.context)
            .build()
            .perform(post("/test").contentType(MediaType.APPLICATION_JSON).content(text))
            .andExpect(status().isBadRequest());
    

title 属性未定义。所以控制器发送 BadRequest。

【讨论】:

感谢您的快速回复。它现在可以工作了,我清除了 m2 缓存并重建它,可能是版本问题。我稍后会检查是什么原因造成的。我会将此标记为答案。 我试过了,但它适用于大写:spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES。

以上是关于Spring Boot 1.4 自定义内部 Jackson 反序列化的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 1.4:Principal 不能为 null 异常

Spring Boot 自定义 http 错误响应?

spring boot整合 spring security之自定义认证

如何为 Spring Boot 2 添加自定义 MeterRegisty

自从升级到 spring boot 1.4 / spring cloud camden 以来,BeanPropertyRowMapper 不再理解 joda 时间类型

Spring Boot - 手把手教小师妹自定义Spring Boot Starter