controllerrequestparam不传参数空指针异常_【有例⼦源
码】Spring。。。
Java 后端发⼯作中经常会对前端传递过来的参数做⼀些校验,在业务中还要抛出异常或者不断的返回异常时的校验信息,充满了 if-else 这种校验代码,在代码中相当冗长。
例如说,⽤户注册时,会校验⼿机格式的正确性,⽤户名的长度等等。虽说前端也可以做参数校验,但是为了保证我们 API 接⼝的可靠性,以保证最终数据⼊库的正确性,后端进⾏参数校验不可忽视。Hibernate Validator提供了⼀种统⼀⽅便的⽅式,让我们快速的实现参数校验。
Hibernate Validator使⽤注解,实现声明式校验。⽽在实现原理上,也是基于 Spring AOP 拦截,实现校验相关的操
作。straints包下,定义了⼀系列的约束注解。⽂末会贴上⼀些常⽤的注解。如果项⽬的框架是 SpringBoot 的话,在spring-boot-starter-web 中已经包含了 Hibernate-validator 的依赖(版本 < 2.3)。
2.3以后的版本中 spring-boot-starter-web已经去除了这个依赖,需要⼿动引⼊ Hibernate-validator依赖。本⽂已将版本升级为2.
3.3。
org.springframework.bootspring-boot-starter-validation
“ ”
RequestBody参数校验
1、创建实体类
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.straints.Length;
import straints.*;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
/**
* ⽤户ID
*/
@NotNull(message = "⽤户id不能为空")
private Long userId;
/**
* ⽤户名
*/
@NotBlank(message = "⽤户名不能为空")
@Length(max = 20, message = "⽤户名不能超过10个字符")
@Pattern(regexp = "^[\\u4E00-\\u9FA5A-Za-z0-9\\*]*$", message = "⽤户名限制:最多10字符,包含⽂字、字母和数字")
@Pattern(regexp = "^[\\u4E00-\\u9FA5A-Za-z0-9\\*]*$", message = "⽤户名限制:最多10字符,包含⽂字、字母和数字")    private String username;
/**
* 密码
*/
@NotBlank(message = "密码不能为空")
private String password;
/**
* ⼿机号
*/
@NotBlank(message = "⼿机号不能为空")
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "⼿机号格式有误")
private String mobile;
/**
* 性别
*/
@NotNull(message = "性别不能为空")
private Integer sex;
/**
* 年龄
*/
validation框架@NotNull(message = "年龄不能为空")
@Min(value = 1, message = "年龄最⼩为1岁")
@Max(value = 120, message = "年龄最⼤为120岁")
private Integer age;
/
**
* 邮箱
*/
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式错误")
private String email;
}
2、创建 controller
se.pojo.User;
slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class UserController {
/**
* controller⽅法的⼊参⾥⾯在实体类前⾯加上@Validated
*/
@PostMapping("/user")
public void add(@RequestBody @Validated User user) {
log.info("user====={}", user);
}
}
3、创建全局异常处理器
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
/
**
* 全局异常处理器
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* post⽅式提交json数据,参数校验失败后,会抛出⼀个MethodArgumentNotValidException
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {        // 获取所有的错误
// List fieldErrors = e.getBindingResult().getFieldErrors();
// 获取错误提⽰
// System.out.(0).getDefaultMessage());
// 获取错误字段
// System.out.(0).getField());
// 将所有的错误提⽰使⽤";"拼接起来并返回
StringJoiner sj = new StringJoiner(";");
// 此处通常定义⼀个全局相应对象返回
Map map = new HashMap<>();
// 此处状态码可以通过枚举或者常量定义
map.put("code", 1001);
map.put("msg", sj.toString());return map;
}
/**
* get⽅式提交参数,参数校验失败后,会抛出⼀个ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
public Map handleConstraintViolationException(ConstraintViolationException e) {
StringJoiner sj = new StringJoiner(";");
Map map = new HashMap<>();
map.put("code", 1001);
map.put("msg", sj.toString());return map;
}
}
4、测试
效果符合预期!
RequestParam/PathVariable参数校验
/**
* ⼊参校验时,Controller上⾯要加:@Validated
* @RequestParam⽅式绑定参数
*/
@GetMapping("/get1")
public void get1(@RequestParam("id") @NotNull(message = "id不能为空") Integer id,
@RequestParam("name") @NotBlank(message = "name不能为空") @Length(max = 10, message = "⽤户名不能超过10个字符") String name) {        log.info("id:{},name:{}", id, name);
}
/**
* @PathVariable⽅式绑定参数
*/
@GetMapping("/get2/{id}")
public void get2(@PathVariable("id") @Min(value = 0, message = "id最⼩为0") Integer id) {
log.info("id:{}", id);
}
@Valid 和 @Validated
绝⼤多数场景下,我们使⽤ @Validated 注解即可。
⽽在有嵌套校验的场景,我们使⽤ @Valid 注解添加到成员属性上。参考:
public class Dog {
@NotBlank(message = "狗的名字不能为空")
private String name;
}