当前位置: 首页 > 知识库问答 >
问题:

java - spring boot中入参校验的疑问?

束新
2023-08-02

1.spring boot 版本: v2.7.14-SNAPSHOT

  1. @RestController
  2. maven:

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

问题描述:
我的接口有get和post两个类型, 其中post使用的是如下:

postApiMethod(@RequestBody @Valid TopicCreateDto topicCreateDto)

然后在dto中写类似 @NotNull 的注解是生效的(我捕获了MethodArgumentNotValidException异常), 生成的结果类似:

校验失败:parentId:不能为null, 

但是我的GET接口我做了如下工作:

  1. controller类上面 添加 @Validated
  2. postApiGet(@RequestParam Long feedId)

不符合我预期的结果:

Required request parameter 'feedId' for method parameter type Long is not present

我想要的结果是:

校验失败:feedId:不能为null,

其他尝试:

postApiGet(@RequestParam @NotNull Long feedId),也提示为不符合预期的结果

所以我该如何让检验结果统一成这样的结果格式(xxx不能为null类似)呢?

共有2个答案

林弘文
2023-08-02

在Spring Boot中,对于GET请求和POST请求的参数校验,处理方式是有差异的。对于GET请求的参数校验,Spring Boot默认会在请求参数缺失时直接报错,而不会触发校验异常。这是因为在GET请求中,请求参数是直接作为URL的一部分,而不像POST请求一样在请求体中,所以无法使用@RequestBody注解来触发校验。

如果你希望在GET请求的参数校验时也能像POST请求一样触发校验异常并返回统一的错误格式,可以使用自定义的校验器和异常处理器来实现。下面是一种可能的解决方案:

自定义校验器:创建一个自定义的校验器,在该校验器中添加对GET请求参数的校验逻辑。这样,无论是GET还是POST请求,在参数校验失败时都会触发校验异常。
java
Copy code
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {NotNullValidator.class})
@Documented
public @interface NotNullParam {

String message() default "{javax.validation.constraints.NotNull.message}";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};

}
自定义校验器的实现:实现自定义校验器的逻辑,对GET请求的参数进行校验。这里以非空校验为例。
java
Copy code
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class NotNullValidator implements ConstraintValidator<NotNullParam, Object> {

@Overridepublic boolean isValid(Object value, ConstraintValidatorContext context) {    return value != null;}

}
异常处理器:定义一个全局异常处理器,在该处理器中捕获校验异常,并返回统一的错误格式。
java
Copy code
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(BindException.class)public ResponseEntity<Object> handleValidationException(BindException ex) {    String errorMessage = ex.getFieldError().getDefaultMessage();    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorMessage);}

}
以上是一种解决方案,通过自定义校验器和异常处理器,可以实现在GET请求和POST请求中统一处理参数校验异常并返回统一的错误格式。请注意在实际使用时根据自己的业务逻辑进行适当调整。

慕容灿
2023-08-02

把GET请求的参数封装成一个对象,然后在这个对象的类上加JSR-303注解进行校验就行:

@GetMapping("/api")public String apiGet(@Valid ApiGetRequest request) {    // ...}public class ApiGetRequest {    @NotNull    private Long feedId;    // getters and setters}

然后再自定义一个全局的异常处理器:

@ControllerAdvicepublic class GlobalExceptionHandler {    @ExceptionHandler(MissingServletRequestParameterException.class)    @ResponseBody    public String handleMissingParams(MissingServletRequestParameterException ex) {        String name = ex.getParameterName();        // 格式化返回的错误信息        return "校验失败:" + name + ":不能为null";    }}
 类似资料:
  • 本文向大家介绍springboot使用校验框架validation校验的示例,包括了springboot使用校验框架validation校验的示例的使用技巧和注意事项,需要的朋友参考一下 b/s系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的。 Spring3支持JSR-303验证框架,JSR-303 是Java

  • 本文向大家介绍SpringBoot使用validation-api实现参数校验的示例,包括了SpringBoot使用validation-api实现参数校验的示例的使用技巧和注意事项,需要的朋友参考一下 我们在开发Java项目的时候,经常需要对参数进行一些必填项、格式、长度等进行校验,如果手写代码对参数校验,每个接口会需要很多低级的代码,这样会降低代码的可读性。那么我们能不能使用一种比较优雅的方式

  • 业务参数校验采用JSR-303方式,关于JSR-303介绍可以参考这篇博文:JSR 303 - Bean Validation 介绍及最佳实践 在参数中使用注解即可,框架会自动进行验证。如下面一个添加商品接口,它的参数是GoodsParam @Api(name = "goods.add") public void addGoods(GoodsParam param) { ... } 在G

  • 业务参数校验采用JSR-303方式,关于JSR-303介绍可以参考这篇博文:JSR 303 - Bean Validation 介绍及最佳实践 在参数中使用注解即可,框架会自动进行验证。如下面一个添加商品接口,它的参数是GoodsParam @Open("goods.add") @RequestMapping("/goods/add") public void addGoods(GoodsPara

  • 1 环境变量(隐藏的输入) 环境变量是隐藏的输入。它们存在并影响程序行为。在编程中忽略它们的存在可能导致安全隐患。 PATH 在 Shell 中运行命令时,Shell 会使用 PATH 环境变量搜索所有命令。 下面会发生什么呢? system("mail"); 攻击者可以将 PATH 修改成下面,并使当前目录下的mail执行。 PATH=".:$PATH"; export PATH IFS I

  • 本文向大家介绍Springboot 自定义校验代码实例,包括了Springboot 自定义校验代码实例的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了Springboot 自定义校验代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 StartWithValidation.class StartWithValidator.clas