-->

参数校验与统一异常处理

1. 说明

SprinBoot中集成参数校验Validator,Validator框架就是为了解决开发人员在开发的时候少写代码,提升开发效率;Validator专门用来进行接口参数校验,例如常见的必填校验,email格式校验,用户名必须位于6到12之间 等等...

2. SpringBoot中集成参数校验代码实现

第一步,引入依赖

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation:2.7.3'

注:从springboot-2.3开始,校验包被独立成了一个starter组件,所以需要引入validation和web,而springboot-2.3之前的版本只需要引入 web 依赖就可以了。

第二步,定义要参数校验的实体类

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
@TableName("admin_auctioneer")
public class Auctioneer {

    private Integer id;

    @NotNull(message = "拍卖师编号不能为空")
    @NotBlank(message = "拍卖师编号不能为空")
    private String pmsbh;

    @NotNull(message = "拍卖师姓名不能为空")
    @NotBlank(message = "拍卖师姓名不能为空")
    private String pmsxm;

    @NotNull(message = "拍卖师证书编号不能为空")
    @NotBlank(message = "拍卖师证书编号不能为空")
    private String pmszsbh;

    private String pmszsz;

}

在实际开发中对于需要校验的字段都需要设置对应的业务提示,即message属性。

常见的约束注解如下:

image

第三步,定义校验类进行测试

import com.example.pmxt.common.ReturnResult;
import com.example.pmxt.domain.Auctioneer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/auctioneers")
@Validated
public class AuctioneerController {

    @Value("${file.location}")
    String filelocation;
    @Value("${file.path}")
    String filepath;
    @Value("${file.domainname}")
    String domainname;
    private final AuctioneerService auctioneerService;

    @Autowired
    public AuctioneerController(AuctioneerService auctioneerService) {
        this.auctioneerService = auctioneerService;
    }

    @GetMapping()
    public ReturnResult getauctioneerall(){
        return ReturnResult.buildSuccessResult(auctioneerService.list());
    }

    @GetMapping("/{pmsbh}")
    public ReturnResult getbypmsbh(@PathVariable @Validated String pmsbh){
        Map<String,Object> map = new HashMap<>();
        map.put("pmsbh",pmsbh);
        return ReturnResult.buildSuccessResult(auctioneerService.listByMap(map));
    }

    @PostMapping()
    public ReturnResult addauctioneer(@RequestBody @Validated Auctioneer auctioneer){
        try {
            // 获取文件名
            String FileName = auctioneer.getPmszsz().substring(auctioneer.getPmszsz().lastIndexOf("/"));
            // 复制文件
            Files.copy(Paths.get(filelocation + "/auctioneer/temp/" + FileName), Paths.get(filelocation + "/auctioneer/" + FileName));
            // 删除临时文件
            Files.delete(Paths.get(filelocation + "/auctioneer/temp/" + FileName));
            // 保存新的url
            auctioneer.setPmszsz(auctioneer.getPmszsz().replace("/temp",""));
            // 存入数据库
            if(auctioneerService.save(auctioneer)){
                return ReturnResult.buildSuccessResult(1);
            }
            else{
                return ReturnResult.buildSuccessResult(0);
            }
        }
        catch (IOException e){
            return ReturnResult.buildFailureResult("logo/officialSeal 文件url不正确");
        }
    }

    @DeleteMapping("/{id}")
    public ReturnResult deletebyid(@PathVariable @Validated Integer id){
        return ReturnResult.buildSuccessResult(auctioneerService.removeById(id));
    }

    @PutMapping()
    public ReturnResult updateauctioneer(@RequestBody @Validated Auctioneer auctioneer){
        return ReturnResult.buildSuccessResult(auctioneerService.updateById(auctioneer));
    }

    @PostMapping("/addpmszhz")
    public ReturnResult addCarousel(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return ReturnResult.buildFailureResult("请传入文件");
        } else {
            try {
                // 保存图片
                // 服务器文件名
                String serverFilename = UUID.randomUUID().toString().substring(0, 8)
                        + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
                // 创建目录、存储图片地址目录
                String path = filelocation + "/auctioneer/temp/";
                // 存储图片的url
                Files.createDirectories(Paths.get(path));
                // 保存
                file.transferTo(Path.of(path, serverFilename));

                return ReturnResult.buildSuccessResult(domainname + "/download/auctioneer/temp/" + serverFilename);

            } catch (Exception e) {
                e.printStackTrace();
                return ReturnResult.buildFailureResult(e.toString());
            }
        }
    }
}

参数异常加入全局异常处理器

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;

@RestControllerAdvice
public class MethodArgumentNotValidExceptionHandler {

    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ReturnResult handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        StringBuilder sb = new StringBuilder("校验失败:");
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", ");
        }
        String msg = sb.toString();
        return ReturnResult.buildFailureResult(415, msg,null);
    }

    @ExceptionHandler({ConstraintViolationException.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ReturnResult handleConstraintViolationException(ConstraintViolationException ex) {
        return ReturnResult.buildFailureResult(415, ex.getMessage(),null);
    }


}

参考文章:
SpringBoot 如何进行参数校验,老鸟们都这么玩的!

posted @ 2022-11-03 15:09  ꧁ʚ星月天空ɞ꧂  阅读(38)  评论(0)    收藏  举报