springboot,参数校验,自动处理异常@Valid

springboot 对外提供接口,对于接收参数处理
一般情况下,是传JSON方式,也有使用 get方式传key和value 方式的

先把POJO类写上去

package com.smk.mall.action.web.hz;

import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

public class TestBean implements java.io.Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Min(value=10,message = "id最小值是10")
	@Max(value = 20,message = "id最大值是20")
	private Integer id;
	
	@NotNull(message="name 不能为空")
	private String name;
	
	@NotNull(message = "年龄不能为空")
	private Long age;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

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

	public Long getAge() {
		return age;
	}

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

	@Override
	public String toString() {
		return "TestBean [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
	
}

get 方式传参数

@RequestMapping("htm/hz")
@RestController
@Scope("prototype")
public class HzTesWebAction {

	@RequestMapping("test")
	public FMsgResponse insertBatch(@Valid TestBean testBean) {
		System.out.println(testBean);
		return new FMsgResponse(EMsg.Success,testBean);
	}

}

POST json 方式

@RequestMapping("htm/hz")
@RestController
@Scope("prototype")
public class HzTesWebAction {

	@RequestMapping("test")
	public FMsgResponse insertBatch(@RequestBody @Valid TestBean testBean) {
		System.out.println(testBean);
		return new FMsgResponse(EMsg.Success,testBean);
	}

}

对比之下,只是多了一个 @RequestBody 注解,接口请求中必须
添加请求头Content-Type : application/json

这种情况下,接口请求参数如果不满足pojo中定义的类,会直接抛出异常
springboot,参数校验,自动处理异常@Valid_第1张图片

统一处理异常

如果校验不通过,就在异常中处理,统一输出格式


@ControllerAdvice
public class RequestExceptionHandle {
	
	@ExceptionHandler(value = Exception.class)
	@ResponseBody
	public FMsgResponse handler(Exception e) {
		FMsgResponse m= null;
		if (e instanceof RequestException) {
			RequestException re = (RequestException) e;
			m = new FMsgResponse(re);
		} else if(e instanceof MethodArgumentNotValidException) {
		//判断是 校验异常,就处理
			e.printStackTrace();
			try {
				MethodArgumentNotValidException me = (MethodArgumentNotValidException) e;
				StringBuilder b = new StringBuilder();
				for (ObjectError error : me.getBindingResult().getAllErrors()) {
				//获取校验的信息
					b.append(error.getDefaultMessage()).append(",");
				}
				// 封装成自己固定的格式
				m=  new FMsgResponse(EMsg.Param_Not_Right,b.toString());
			} catch (Exception e1) {
				e1.printStackTrace();
				m=  new FMsgResponse(EMsg.Sys_error);
			}
		}else {
			e.printStackTrace();
			m=  new FMsgResponse(EMsg.Sys_error);
		}
		return m;
	}
}

啦啦啦 ,然后就这样就OK了

后话,如果说想单独的处理其中一个接口的异常,那还有另外一种方式实现

@RequestMapping("htm/hz")
@RestController
@Scope("prototype")
public class HzTesWebAction {

	@RequestMapping("test")
	public FMsgResponse insertBatch(@RequestBody @Valid TestBean testBean,BindingResult re) {
	// 接口参数中添加  BindingResult  异常处理结果
		re.getAllErrors();
		System.out.println(testBean);
		return new FMsgResponse(EMsg.Success,testBean);
	}

}

这种方式允许你 自己处理异常信息,可以单独处理
如果使用这种方式的话,也是有一批的这样的接口呢,
(虽说有点画蛇添足,但是还是说一下)

定义一个AOP 切面,切到这个异常处理的地方

/**
 * 对外部请求的日志切面
 * 
 * @author luoyang
 *
 */
//@Component
@Aspect
public class ValidAspect {
	/*
	 *    切入到参数
	 *  args(..,org.springframework.validation.BindingResult)
	 * 
	 */
	@Around("execution(* com..*.action.web..*Action.*(..)) && !execution(*  com..*.action.web..*BaseAction.*(..)) "
			 + "&& args(..,org.springframework.validation.BindingResult)" )
	public Object doServiceClient(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("进去切面");
		Object[] o  = pjp.getArgs();
		for (Object object : o) {
			if(object instanceof BindingResult) {
				BindingResult re = (BindingResult) object;
				if(re.hasErrors()) {
					StringBuilder b = new StringBuilder();
					for (ObjectError error : re.getAllErrors()) {
						b.append(error.getDefaultMessage()).append(",");
					}
					throw new RequestException(EMsg.Param_Not_Right,b.toString());
				}
			}
		}
		/*
		 * if (bindingResult.hasErrors()) { retVal = doErrorHandle(bindingResult); }
		 * else { retVal = pjp.proceed(); }
		 */
		return pjp.proceed();

	}

	public Object doErrorHandle(BindingResult r) {
		System.out.println(r);
		return new FMsgResponse(EMsg.Fail);
	}
}

你可能感兴趣的:(springboot,参数校验,自动处理异常@Valid)