java Jackson验证未在未知属性上失败

irtuqstp  于 2023-10-14  发布在  Java
关注(0)|答案(2)|浏览(84)

如果json有一个额外的字段,则以下POJO的初始化应该失败,因为Jackson文档说默认设置为FAIL_ON_UKNOWN_PROPERTIES

@Getter
@Setter
@FieldNameConstants
@ToString
@Builder
@Document(collection = "form_layouts")
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
@Jacksonized
public class MyFormLayout extends AuditableDocument {

    @NotNull
    private Boolean selected;
    @NotNull
    private Boolean disabled;
    @NotEmpty
    private List<Layout> layout;

    @NotBlank
    @EqualsAndHashCode.Include
    private String realmId;
}

我预计这个测试会失败与UnrecognizedPropertyException,它并没有即使在Jackson设置这个属性

@SpringJUnitConfig
@TestPropertySource(
        properties = {
                "spring.jackson.deserialization.fail-on-unknown-properties=true"
        }
)
@AutoConfigureJson
@DisplayName("Form Layout Deserialisation")
public class MyFormLayoutDeserialisationTest {

    @Autowired
    Jackson2ObjectMapperBuilder objectMapperBuilder;
    ObjectMapper objectMapper;

    @BeforeEach
    void setUp() {
        objectMapper = objectMapperBuilder.build();
    }

    @Test
    @DisplayName("fails loading seeder json if the keys don't match to object fields")
    void testForcesJsonToMatchFormTemplate(@Value("classpath:bad_nform_layout.json") Resource badLayout) {
        Assertions.assertThrows(UnrecognizedPropertyException.class, () -> objectMapper.readValue(Files.readString(Path.of(badLayout.getFile().getAbsolutePath())), new TypeReference<>() {
        }), "Seeder JSON should have the exact keys and fields declared in the MyFormLayout object");
    }
}

测试失败并显示消息

org.opentest4j.AssertionFailedError: Seeder JSON should have the exact keys and fields declared in the MyFormLayout object ==> Expected com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException to be thrown, but nothing was thrown.

JSON文件

[
  {
    "selected": false,
    "disabled": true,
    "app": "blox",
    "foo": "bar",
    "layout": [
      {
        "id": "B-1",
        "x": 0,
        "y": 0,
        "w": 12,
        "h": 7
      },
      {
        "id": "B-2",
        "x": 13,
        "y": 0,
        "w": 4,
        "h": 4
      },
      {
        "id": "B-3",
        "x": 0,
        "y": 8,
        "w": 12,
        "h": 3
      },
      {
        "id": "B-4",
        "x": 13,
        "y": 5,
        "w": 4,
        "h": 6
      }
    ]
  }
  ...
]

"foo": "bar"是未知属性,它应该没有通过验证。

vsmadaxz

vsmadaxz1#

1.标注效果:确保Lombok中的@Jacksonized之类的注解不会改变ObjectMapper的默认行为,特别是关于未知属性的处理。
1.启用功能的全局ObjectMapper Bean示例:您可以创建一个启用了FAIL_ON_UNKNOWN_PROPERTIES功能的ObjectMapper bean,并在整个应用程序中使用它。以下是如何在Sping Boot @Configuration类中执行此操作:
public class MyConfiguration {

@Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
        return objectMapper;
    }
}

1.JunitTest分离株:

@Test
 @DisplayName("GIVEN a JSON string with unknown properties WHEN deserialized THEN should throw UnrecognizedPropertyException")
 void debugTest() {
     ObjectMapper localMapper = new ObjectMapper();
     localMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);

     String jsonString = "{\"selected\": false, \"disabled\": true, \"foo\": \"bar\"}";

     Assertions.assertThrows(
         UnrecognizedPropertyException.class,
         () -> localMapper.readValue(jsonString, MyFormLayout.class)
     );
 }
e4yzc0pl

e4yzc0pl2#

将类型引用更改为新的TypeReference<List<MyFormTemplate>>() {}修复了它。

相关问题