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中定义的类,会直接抛出异常
在这里插入图片描述

统一处理异常

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


@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);
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值