【springboot 从入门到开发】5.3 接口的请求字段校验

导读:本篇文章讲解 【springboot 从入门到开发】5.3 接口的请求字段校验,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

请求字段的校验在接口开发中也是必不可少的,最常见的就是要判断字段必须不为空。

如上一章节的”提交学生信息”接口,如果我们要校验姓名不能为空,则需要在方法体内校验它。

    /**
     * 提交学生信息
     *
     * @param studentDto
     * @return
     */
    @PutMapping("/student")
    public StudentDto student(@RequestBody StudentDto studentDto) throws Exception {

        String name = studentDto.getName();
        if (name == null || name.length() == 0) {
            throw new Exception("姓名不能为空");
        }

        return studentDto;
    }

如果提交的信息字段很多,这样在方法体内就需要对每一个字段都需要写一段这样的判断代码。

那么有没有更优雅的方式?答案肯定是有的,使用@Valid注解。

@Valid注解

首先在pom.xml引入所需的依赖包。

        <!--校验组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

打开右侧的”Maven”,点击一下左上角的小图标,这样项目就可以拉取引入这个新的依赖包。 

【springboot 从入门到开发】5.3 接口的请求字段校验

 这时候,就可以对接口的请求对象”StudentDto”进行校验。

    /**
     * 提交学生信息
     *
     * @param studentDto
     * @return
     */
    @PutMapping("/student")
    public StudentDto student(@RequestBody @Valid StudentDto studentDto) {

        return studentDto;
    }

只要在”StudentDto”前面,加上@Valid注解。

/**
 * 学生dto
 */
public class StudentDto {

    /**
     * 姓名
     */
    @NotBlank(message = "姓名不能为空")
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 性别
     */
    private String sex;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

}

主要在想校验的字段上面,加上@NotBlank注解,即可对这个字段进行判空校验,message参数是可以指定报错信息。

我们来运行一下项目,然后通过postman工具模拟请求,这次我们将name字段设置为空。

【springboot 从入门到开发】5.3 接口的请求字段校验

可以看到,返回信息状态为400 Bad Request。

我们再看看IDE控制台输出了什么信息。

【springboot 从入门到开发】5.3 接口的请求字段校验校验生效了,识别到name这个字段的值不能为空(NotBlank),但是请求的字段值现在为空了,同时也看到我们定义的message信息”姓名不能为空”。

把name字段信息填上,再请求一次,看看校验会不会通过。

【springboot 从入门到开发】5.3 接口的请求字段校验

可以看到能正常返回,说明校验是通过了,因为这时候name字段不空了。

但是这里头又有一个问题,就是这种报错信息不够优雅, 而且前端接口也接收不到我们提示的错误信息啊。这时候,我们就需要对错误信息做一个统一的处理。

@ControllerAdvice注解 和 @ExceptionHandler注解

@ControllerAdvice注解表示我们定义的是一个控制器增强类,当其他任何控制器发生异常且异常类型符合@ExceptionHandler注解中指定的异常类时,原请求将会被拦截到这个我们自定义的控制器方法中。

我们来看看这两个注解结合到项目中是什么使用的。

首先,我们创建一个exception包路径,并其下创建一个控制器增强类MyExceptionHandler

package org.liurb.springboot.demo.exception;

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

@RestControllerAdvice
public class MyExceptionHandler {


    @ExceptionHandler(MethodArgumentNotValidException.class)
    public String methodArgumentNotValidExceptionHandler(HttpServletRequest httpServletRequest, MethodArgumentNotValidException e) {
        //打印第一条错误信息
        String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();

        System.out.println("参数校验异常:" + message);

        return message;
    }

}

这里使用的是@RestControllerAdvice注解,因为我们控制器controller加入的注解是@RestController,所以这里是一一对应的。

下面的methodArgumentNotValidExceptionHandler方法可以看到,我们这边拦截的是MethodArgumentNotValidException异常,因为校验注解这边报的异常是这个,所以我们需要处理的是这个异常。

这里需要注意的是每个Exception异常获取的message方式可能会有所不同,所以具体要看错误信息要怎么获取。

我们再用postman模拟请求一次看看这时候返回的错误信息是什么。

【springboot 从入门到开发】5.3 接口的请求字段校验

这时候我们看到返回的是我们指定的错误信息内容了,是不是很方便,而且前端页面也能够提示我们提示的错误信息内容了。

要使用这种统一异常处理,有个注意的地方就是,异常必须要抛出controller这层,才会被MyExceptionHandler这个类捕获。

意思就是说,如果我们是以下这种写法,就不会被捕获。

    @GetMapping("/hello_world")
    public String helloWorld() {
        
        try {
            
            System.out.println(1/0);
            
        }catch (Exception e) {
            System.out.println("异常:" + e.getMessage());
        }

        return "Hello World!";
    }

在方法体内try/catch了异常,没有往controller层再抛出异常的话,统一异常处理是不起操作的。

【springboot 从入门到开发】5.3 接口的请求字段校验

IDE控制台输出。

【springboot 从入门到开发】5.3 接口的请求字段校验

 如果将try/catch去掉。

    @GetMapping("/hello_world")
    public String helloWorld() {
        
        System.out.println(1/0);
            
        return "Hello World!";
    }

再请求一次。

【springboot 从入门到开发】5.3 接口的请求字段校验

IDE控制台输出。

【springboot 从入门到开发】5.3 接口的请求字段校验

这里统一异常处理类我们加上了最大的异常Exception捕获。

package org.liurb.springboot.demo.exception;

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

@RestControllerAdvice
public class MyExceptionHandler {



    @ExceptionHandler(MethodArgumentNotValidException.class)
    public String methodArgumentNotValidExceptionHandler(HttpServletRequest httpServletRequest, MethodArgumentNotValidException e) {
        //打印第一条错误信息
        String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();

        System.out.println("参数校验异常:" + message);

        return message;
    }

    @ExceptionHandler(Exception.class)
    public String globalException(HttpServletRequest request, Exception e) {

        String message = e.getMessage();

        System.out.println("exception异常:" + message);

        return message;
    }

}

意思是,如果前面的异常类没有定义的(或者没有捕获到的),都会走到Exception这边的处理来。


另附上一些常用的校验注解和作用说明

常用校验注解

@NotNull 被注释的元素必须不为 null

@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max, min) 被注释的元素的大小必须在指定的范围内

@NotBlank 不为null并且包含至少一个非空白字符

@NotEmpty 不为null并且不为空

@Digits 可设定最大整数位数和最大小数位数

@Email 校验是否符合Email格式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/93620.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!