Validation自动化校验请求参数

前言

        请求参数校验是开发过程中经常需要做的事,为了避免用大量的if判断,这里推荐使用javax.validation中的注解去校验参数,配合springboot 全局异常-ExceptionHandler来处理校验参数时抛出的异常并封装成视图返回

源码

控制层请求

@RequestMapping(value = "/edit", method = RequestMethod.POST)
public Result<ExamPaperEditRequestVM> edit(@RequestBody @Valid ExamPaperEditRequestVM model) {
    ExamPaper examPaper = examPaperService.savePaperFromVM(model, getCurrentUser());
    ExamPaperEditRequestVM newVM = examPaperService.examPaperToVM(examPaper.getId());
    return Result.ok(newVM);
}

实体类

package com.sed.exam.viewmodel.admin.exam;

import lombok.Data;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;

@Data
public class ExamPaperEditRequestVM {

    private Integer id;
    @NotNull
    private Integer level;
    @NotNull
    private Integer subjectId;
    @NotNull
    private Integer paperType;
    @NotBlank
    private String name;
    @NotNull
    private Integer suggestTime;

    private List<String> limitDateTime;

    @Size(min = 1,message = "请添加试卷标题")
    @Valid
    private List<ExamPaperTitleItemVM> titleItems;

    private String score;
}

全局异常处理类

由于校验参数时,对于不符合预期的参数会抛出MethodArgumentNotValidException异常,所以,全局异常处理类如下:


package com.sed.exam.common.handler;

import com.sed.commons.result.BusinessException;
import com.sed.commons.result.Result;
import com.sed.commons.result.ResultCodeEnum;
import com.sed.exam.utility.ErrorUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
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.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;


/**
 * @author sed
 * @ClassName: ControllerExceptionHandler
 * @Description: 控制层全局异常处理
 * @date 2021-08-31
 */
@ControllerAdvice
@ResponseBody
public class ControllerExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class);

    @ExceptionHandler(value = {ConstraintViolationException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result constraintViolationException(ConstraintViolationException ex) {
        logger.info(ex.getMessage());
        return new Result(HttpStatus.BAD_REQUEST.value(), "参数错误");
    }

    @ExceptionHandler(value = {IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result illegalArgumentException(IllegalArgumentException ex) {
        logger.info(ex.getMessage());
        return new Result(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
    }

    @ExceptionHandler(value = {NoHandlerFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Result noHandlerFoundException(Exception ex) {
        logger.info(ex.getMessage());
        return new Result(HttpStatus.NOT_FOUND.value(), ex.getMessage());
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        //logger.error("缺少请求参数", e);
        return new Result(HttpStatus.NOT_FOUND.value(), e.getMessage());
    }


    @ExceptionHandler(value = {Exception.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result unknownException(Exception ex) {
        logger.error("", ex);
        if (ex instanceof BusinessException) {
            BusinessException businessException = (BusinessException) ex;
            if (businessException.getCode() != null) {
                return new Result(businessException.getCode(), ex.getMessage());
            } else {
                return new Result(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage());
            }
        }
        if (ex instanceof MethodArgumentTypeMismatchException) {
            return new Result(HttpStatus.INTERNAL_SERVER_ERROR.value(), "参数类型错误:" + ex.getMessage());
        } else if (ex instanceof BusinessException) {

            return new Result(ResultCodeEnum.SYSTEMERROR.getCode(), ResultCodeEnum.SYSTEMERROR.getName());
        }

        return new Result(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage());
    }

    /**
     * MethodArgumentNotValidException
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Result handler(MethodArgumentNotValidException e) {
        String errorMsg = e.getBindingResult().getAllErrors().stream().map(file -> {
            FieldError fieldError = (FieldError) file;
            return ErrorUtil.parameterErrorFormat(fieldError.getField(), fieldError.getDefaultMessage());
        }).collect(Collectors.joining());
        return new Result<>(ResultCodeEnum.ParameterValidError.getCode(), errorMsg);
    }

    /**
     * BindException
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Result handler(BindException e) {
        String errorMsg = e.getBindingResult().getAllErrors().stream().map(file -> {
            FieldError fieldError = (FieldError) file;
            return ErrorUtil.parameterErrorFormat(fieldError.getField(), fieldError.getDefaultMessage());
        }).collect(Collectors.joining());
        return new Result<>(ResultCodeEnum.ParameterValidError.getCode(), errorMsg);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值