您的位置:首页 > 编程语言 > Java开发

SpringMVC优雅的实现数据校验

2018-01-06 15:18 661 查看
我们在使用SpringMVC提供接口时,所提供的参数难免会进行参数的合法性校验,比如非空校验,最原始的办法就是手动校验,比如下面的代码:

if(StringUtils.isBlank(authorize.getClientId())){
log.debug("clientId为必填项!");
}


如果一个两个参数还好,如果参数很多比如几十个,那么就要判断几十次,代码量剧增,可读性也不好。

SpringMVC为我们提供了Valid,通过Valid很方便的进行数据的合法性校验,请看代码:

@GetMapping("authorize")
public void authorize(@Valid AuthorizeIn authorize, BindingResult ret){
if(result.hasFieldErrors()){
List<FieldError> errorList = result.getFieldErrors();
//通过断言抛出参数不合法的异常
errorList.stream().forEach(item -> Assert.isTrue(false,item.getDefaultMessage()));
}
}
public class AuthorizeIn extends BaseModel{

@NotBlank(message = "缺少response_type参数")
private String responseType;
@NotBlank(message = "缺少client_id参数")
private String ClientId;

private String state;

@NotBlank(message = "缺少redirect_uri参数")
private String redirectUri;

public String getResponseType() {
return responseType;
}

public void setResponseType(String responseType) {
this.responseType = responseType;
}

public String getClientId() {
return ClientId;
}

public void setClientId(String clientId) {
ClientId = clientId;
}

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

public String getRedirectUri() {
return redirectUri;
}

public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
}


在controller的方法需要校验的参数后面必须跟BindingResult,否则无法进行校验。但是这样会抛出异常,对用户而言不太友好!

那怎么办呢?

很简单,我们可以利用Spring的AOP特性,拦截异常,并输出友好的参数。接下来我们就来实现异常的拦截:

@Component
@Aspect
public class WebExceptionAspect implements ThrowsAdvice{

public static final Logger logger = LoggerFactory.getLogger(WebExceptionAspect.class);

//拦截被GetMapping注解的方法    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
private void webPointcut() {
}

@AfterThrowing(pointcut = "webPointcut()",throwing = "e")
public void afterThrowing(Exception e) throws Throwable {
logger.debug("exception 来了!");
if(StringUtils.isNotBlank(e.getMessage())){
writeContent(e.getMessage());
}else{
writeContent("参数错误!");
}

}

/**
* 将内容输出到浏览器
*
* @param content
*            输出内容
*/
private void writeContent(String content) {
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getResponse();
response.reset();
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "text/plain;charset=UTF-8");
response.setHeader("icop-content-type", "exception");
PrintWriter writer = null;
try {
writer = response.getWriter();

writer.print((content == null) ? "" : content);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


这样当我们传入不合法的参数时就会进入WebExceptionAspect类,从而输出友好参数。

我们再把验证的代码单独封装成方法:

protected void validate(BindingResult result){
if(result.hasFieldErrors()){
List<FieldError> errorList = result.getFieldErrors();
errorList.stream().forEach(item -> Assert.isTrue(false,item.getDefaultMessage()));
}
}


这样每次参数校验只需要调用validate方法就行了,我们可以看到代码的可读性也大大的提高了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息