简体   繁体   English

Springboot - 验证@RequestBody

[英]Springboot - validate @RequestBody

Question: It is possible to validate the JSON payload of a request body, without specifically writing if statements?问题:是否可以验证请求主体的 JSON 负载,而无需专门编写 if 语句? Maybe via annotation or configuration?也许通过注释或配置?

I have a very easy POJO:我有一个非常简单的 POJO:

public class Foo {

    private int important;
    private String something;

//constructors, getter, seters, toString
}

And a very easy controller class:一个非常简单的 controller class:

@SpringBootApplication
@RestController
public class QuestionController {

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

    @GetMapping(value = "/question")
    Mono<String> question(@RequestBody Foo foo) {
        System.out.println("The object foo, with value for important = " + foo.getImportant() + " and something = " + foo.getSomething());
        return Mono.just("question");
    }

}

If I query with a payload such as:如果我查询有效载荷,例如:

{
    "important": 42,
    "something": "value"
}

Everything is working perfectly fine, very happy.一切都很好,非常高兴。

However, if there is a typo: (note the typo on "important")但是,如果有错字:(注意“重要”的错字)

{
    "importantWithTypo": 42,
    "something": "value"
}

Or the required "important" is absent (note the JSON is not even complete)或者缺少所需的“重要”(注意 JSON 甚至不完整)

{
    "something": "value"
}

The request and computation are still valid!请求和计算仍然有效! And the value of "important" is 0!而“重要”的值为0!

I do not want Spring to default to 0 and to thinks everything is fine.我不希望 Spring 默认为 0 并认为一切都很好。

I also do not want to change my types from primitives to boxed object.我也不想将我的类型从原始类型更改为盒装 object。

Without me writing something like:没有我写这样的东西:

 @GetMapping(value = "/question")
    Mono<String> question(@RequestBody Foo foo) {
        if (0 == foo.getImportant()) {
            throw new IllegalArgumentException();
        }
        System.out.println("The object foo, with value for important = " + foo.getImportant() + " and something = " + foo.getSomething());
        return Mono.just("question");
    }

What is the most efficient way to resolve this?解决这个问题最有效的方法是什么? Some kind of annotation?某种注释? Or maybe Spring boot configuration?或者 Spring 引导配置?

Thank you谢谢

Add @NotNull annotation on a field (you may need to change type to Integer), and add @Valid annotation on the method parameter of the controller.在字段上添加@NotNull 注解(您可能需要将类型更改为Integer),并在控制器的方法参数上添加@Valid 注解。

Mono<String> question(@Valid @RequestBody Foo foo) {
    ...
}
public class Foo {

    @NotNull
    private Integer important;
    private String something;

//constructors, getter, seters, toString
}

You can find more information here: https://lmonkiewicz.medium.com/the-power-of-spring-rest-api-validation-77be83edef您可以在此处找到更多信息: https : //lmonkiewicz.medium.com/the-power-of-spring-rest-api-validation-77be83edef

The already provided answer covers the answer.已经提供的答案涵盖了答案。

However I would like to elaborate on one thing that you asked.但是,我想详细说明您提出的一件事。

How to fail on this "importantWithTypo": 42,如何在这个“importantWithTypo”上失败:42,

2 aspects to it. 2个方面。

  1. you want to return a 4XX if a required field is not present (this can be achieved by the already given answer) -- @NonNull/@NonEmpty in conjunction with @Validate annotation如果不存在必填字段,您想返回 4XX(这可以通过已经给出的答案来实现)--@NonNull/@NonEmpty 与 @Validate 注释
  2. You want to error out on presence of an unknown field importantWithTypo .您想在出现未知字段importantWithTypo出错。 This can be achieved by jackson's fail_on_unknown_properties property.这可以通过 jackson 的 fail_on_unknown_properties 属性来实现。 (May be default is fail_on_unknown_properties = enabled, I havent checked so not sure). (可能默认是 fail_on_unknown_properties = 启用,我没有检查所以不确定)。

Don't do this 2nd thing.不要做这第二件事。 That will make your 2 services tightly coupled.这将使您的 2 个服务紧密耦合。 By doing this fail_on_unknown_properties = enabled, you are forfeiting the potential opportunity to enhance the consumer/caller service in a nonbreaking fashion.通过执行此 fail_on_unknown_properties = enabled,您将失去以不间断方式增强消费者/呼叫者服务的潜在机会。 You will have to coordinate both the apps releases.您必须协调这两个应用程序版本。

You also need to add these as dependency to use @Valid , @NotNull etc .您还需要将这些添加为依赖项以使用 @Valid 、 @NotNull 等。

 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>

You can read more on this here您可以在此处阅读更多相关信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM