前言
请求参数校验是开发过程中经常需要做的事,为了避免用大量的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);
}
}