【问题标题】:Jackson Deserialization - Wrong body types sucessfully deserializing杰克逊反序列化 - 错误的身体类型成功反序列化
【发布时间】:2021-04-20 03:08:42
【问题描述】:

我正在尝试验证对我的 REST 控制器的 POST 请求,在我的 DTO 类上有一些属性和验证:

EmployeeDTOInput.java

@Getter
@Setter
public class EmployeeDTOInput {

  @NotBlank("name must not be blank!")
  private String name;

  @DecimalMin(value = "0.01", message = "salary must be greather than or equal to $0.01!")
  private BigDecimal salary;

  @NotNull("commission elegible must not be null!")
  private boolean commissionElegible;
}

另外,控制器上有一个有效的检查器:

@PostMapping
public EmployeeDTO store(@RequestBody @Valid EmployeeDTOInput employeeDTOInput) {
 // Controller logic
}

编写了一些测试,我发现如果我的 JSON 请求对象具有这种语法,并且它工作正常:

{
  name: 12345,
  salary: "30000.50"
}

有没有办法拒绝这种请求,我的意思是,根据实际的DTO属性只接受JSON属性类型的100%一致性,只接受浮点格式到salary,字符串格式到name而不是忽略commissionElegible?

我尝试在 application.properties 上添加一些 Jackson 属性:

spring.jackson.deserialization.fail-on-unknown-properties=true
spring.jackson.deserialization.fail-on-ignored-properties=true
spring.jackson.deserialization.fail-on-invalid-subtype=true

还有一些关于 DTO 类的 Jackson 注释:

@Getter
@Setter
public class EmployeeDTOInput {

  @JsonFormat(shape = JsonFormat.Shape.STRING)
  @NotBlank("name must not be blank!")
  private String name;
  
  @JsonFormat(shape = JsonFormat.Shape.NUMBER_FLOAT)
  @DecimalMin(value = "0.01", message = "salary must be greather than or equal to $0.01!")
  private BigDecimal salary;

  @JsonFormat(shape = JsonFormat.Shape.BOOLEAN)
  @NotNull("commission elegible must not be null!")
  private boolean commissionElegible;
}

但请求仍然有效。

有没有办法防止这种“错误”的反序列化并将其配置为抛出异常?

【问题讨论】:

  • 你是如何在测试中发送请求的?你能添加你的测试代码吗?请评论spring-boot版本等
  • 我正在使用 RestAssured 和 Matchers,测试本身没有按预期通过,但我在测试中没有问题,问题当前在 POST 请求上,即允许应该被服务器解释为错误的主体类型,我可以使用任何 REST 客户端重现它。使用 Spring Boot 2.4.1

标签: java json spring jackson


【解决方案1】:

相信你需要配置 ObjectMapper 的 ALLOW_COERCION_OF_SCALARS 属性。

可以通过更改application.properties中的设置来实现:

spring.jackson.mapper.allow-coercion-of-scalars=false

这里是 JavaDoc:

https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/MapperFeature.html#ALLOW_COERCION_OF_SCALARS

【讨论】:

  • 有效!!确实有帮助,但正如 JavaDoc 所说:它实际上将此功能排除在 String 属性中,但现在,相反的工作正常。真的谢谢!
  • 如果您对背景或更多细节感兴趣,该问题已在 jackson-databind github 中讨论。 github.com/FasterXML/jackson-databind/issues/796
猜你喜欢
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
  • 2017-04-25
  • 1970-01-01
  • 2015-04-07
  • 1970-01-01
  • 2017-12-26
  • 2016-11-11
相关资源
最近更新 更多