java后台参数校验
一. 单个参数的校验方式
实现原理:@ControllerAdvice,@Validated注解对参数进行校验
实现方式:
1.创建统一的系统常量
package com.hm.middle_service.common;
/**
* @Author:huangzhimin
* @Date:2020/6/2 描述:系统编码
**/
public class CodeConst {
/**
* 操作成功编码
*/
public static final String SUCESS_CODE = "succes";
public static final String SUCESS_CODE_MSG = "操作成功";
/**
* 操作失败编码
*/
public static final String FAIL_CODE = "fail";
public static final String FAIL_CODE_MSG = "操作失败";
/**
* 参数异常
*/
public static final String PARAMETER_EXCEPTION_CODE = "parameter_exception";
public static final String PARAMETER_EXCEPTION_CODE_MSG = "参数异常";
}
2.创建统一的返回结果集
import com.hm.middle_service.common.CodeConst;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* Author:huangzhimin
* Date:2020/5/8
* 描述:用户返回给前端
**/
@Getter
@Setter
@ToString
public class ResultBean<T> {
/**
* 系统编码
*/
private String code;
/**
* 系统信息
*/
private String msg;
/**
* 结果集
*/
private T data;
/**
* 默认的构造函数
*/
public ResultBean(){
this.code = CodeConst.SUCESS_CODE;
this.msg = CodeConst.SUCESS_CODE_MSG;
}
//这里使用了lombok组件,不想用的话,直接使用get,set 方法即可
}
3.创建集中校验类
import com.hm.middle_service.bean.ResultBean;
import com.hm.middle_service.common.CodeConst;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* Author:huangzhimin
* Date:2020/5/8
* 描述:单个参数校验
**/
@ControllerAdvice
public class ExceptionAdvice {
@ResponseBody
@ExceptionHandler(value = ConstraintViolationException.class)
public ResultBean ConstraintViolationExceptionHandler(ConstraintViolationException ex) {
ResultBean resultVO = new ResultBean();
Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator();
List<String> msgList = new ArrayList<>();
while (iterator.hasNext()) {
ConstraintViolation<?> cvl = iterator.next();
resultVO.setMsg(cvl.getPropertyPath().toString().split("\\.")[1] + " " + cvl.getMessageTemplate());
resultVO.setCode(CodeConst.PARAMETER_EXCEPTION_CODE);
}
return resultVO;
}
@ResponseBody
@ExceptionHandler(value = Exception.class)
public ResultBean Exception(HttpServletRequest request,Exception e){
ResultBean resultBean = new ResultBean();
resultBean.setCode(CodeConst.FAIL_CODE);
resultBean.setMsg(CodeConst.FAIL_CODE_MSG);
return resultBean;
}
}
4.在controller层实现校验
实现方式:在controller上添加注解@Validated
import com.hm.middle_service.bean.ResultBean;
import com.hm.middle_service.bean.UserBean;
import com.hm.middle_service.service.MiddleService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
/**
* Author:huangzhimin
* Date:2020/3/5
* 描述:
**/
@Validated
@RestController
@RequestMapping("api/middle")
public class MiddleController {
@ResponseBody
@RequestMapping("getNameByID")
public ResultBean getNameByID(@NotNull(message = "不能为空") Integer id){
//参数如果是int 型的需要用Integer 接受,不然可能导致错误捕获不到
ResultBean resultBean = new ResultBean();
try {
if (id == 123){
resultBean.setData("黄治敏");
}else{
resultBean.setData("查无此人");
}
}catch (Exception e){
e.printStackTrace();
}
return resultBean;
}
}
5.试验结果
二.对实体类对象进行校验
1.添加一个校验配置类
import com.hm.middle_service.bean.ResultBean;
import com.hm.middle_service.common.CodeConst;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import java.util.List;
/**
* Author:huangzhimin
* Date:2020/5/8
* 描述:
**/
@Component
@Aspect
public class BindingResultAop {
/**
* Path=com.aop.controller
* 设置切入点: Path为路径根据实际情况替换即可
*/
@Pointcut("execution(* com.hm.middle_service.controller..*.*(..))")
public void method() {
}
/**
* 检查 Controller 方法的参数是否合法 环绕通知:目标方法执行前后分别执行一些代码,发生异常的时候执行另外一些代码
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("method()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
BindingResult bindingResult = null;
for (Object arg : joinPoint.getArgs()) {// 遍历被通知方法(controller方法)的参数列表
if (arg instanceof BindingResult) {// 参数校验结果会存放在BindingResult中
bindingResult = (BindingResult) arg;
}
}
if (bindingResult != null) {
if (bindingResult.hasErrors()) {// 检查是否存在校验错误
List<FieldError> errors = bindingResult.getFieldErrors();// 获取字段参数不合法的错误集合
for (FieldError error : errors) {
ResultBean resultVO = new ResultBean();
resultVO.setMsg(error.getField() + " " + error.getDefaultMessage());
resultVO.setCode(CodeConst.PARAMETER_EXCEPTION_CODE);
return resultVO;
}
}
}
return joinPoint.proceed();// 执行目标方法
}
}
2.创建要校验的bean
import com.hm.middle_service.util.Insert;
import com.hm.middle_service.util.Update;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.validation.constraints.NotNull;
/**
* Author:huangzhimin
* Date:2020/5/8
* 描述:对对象进行校验
**/
@Getter
@Setter
@ToString
public class ValueBean {
/**
* 主键
*/
@NotNull(message = "主键不能空",groups = {Update.class})
private Integer id;
/**
* name
*/
@NotNull(message = "用户名不能为空",groups = {Insert.class,Update.class})
private String name;
/**
* 年龄
*/
@NotNull(message = "年龄不能为空",groups = {Insert.class,Update.class})
private Integer age;
}
注:group 为分组,该类在不同请求中要校验的参数也不同,故需要进行分组处理,Insert.class,Update.class 为两个接口,只是用于标注分组
3.分组举例
public interface Insert {
}
4具体的请求校验方式为
@PostMapping("insertValueBean")
public ResultBean getUserBean(@Validated(Insert.class)@RequestBody ValueBean valueBean, BindingResult bindingResult){
ResultBean resultBean = new ResultBean();
try {
resultBean.setData(valueBean);
}catch (Exception e){
e.printStackTrace();
resultBean.setCode(CodeConst.FAIL_CODE);
resultBean.setMsg(CodeConst.FAIL_CODE_MSG);
}
return resultBean;
}
@PostMapping("updateValueBean")
public ResultBean updateValueBean(@Validated(Update.class)@RequestBody ValueBean valueBean,BindingResult bindingResult){
ResultBean resultBean = new ResultBean();
try {
resultBean.setData(valueBean);
}catch (Exception e){
e.printStackTrace();
resultBean.setCode(CodeConst.FAIL_CODE);
resultBean.setMsg(CodeConst.FAIL_CODE_MSG);
}
return resultBean;
}
注意点:@Validated(Update.class) 标注使用什么组进行校验 ,BindingResult bindingResult 为固定参数
如有问题欢迎大家联系:1411773544@qq.com