1、对象校验
为了接口的健壮性,我们通常除了客户端进行输入合法性校验外,在 Controller 的方法里,我们也需要对参数进行合法性校验,传统的做法是每个方法的参数都做一遍判断,这种方式和上一节讲的异常处理一个道理,不太优雅,也不易维护。
其实,SpringMVC 提供了验证接口,下面请看代码:
实体
package com.demo.entity;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
public class User {
@NotBlank(message = "用户名称不能为空。")
private String userName;
@Range(max = 150, min = 1, message = "年龄范围应该在1-150内。")
private int age;
@NotEmpty(message = "密码不能为空")
@Length(min = 6, max = 8, message = "密码长度为6-8位。")
private String passwd;
public User() {
super();
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
controller类
package com.demo.controller;
import java.util.List;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.demo.entity.User;
import com.demo.result.Result;
import com.demo.util.Validation;
@RestController
@RequestMapping(value="/user")
public class ValidationController {
@RequestMapping(value="/add",method=RequestMethod.POST)
public ModelMap add(@RequestBody @Validated User u,BindingResult result) {
List<?> l = Validation.getValidation(result);
if(l.size() != 0) {
return Result.error(l);
}
return Result.success();
}
}
还需要一个遍历整个校验对象的工具类
package com.demo.util;
import java.util.ArrayList;
import java.util.List;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
public class Validation {
public static List<?> getValidation(BindingResult result) {
List<String> resultList = new ArrayList<>();
if(result.hasFieldErrors()){
List<FieldError> errorList = result.getFieldErrors();
errorList.forEach(item -> resultList.add(item.getField()+" "+item.getDefaultMessage()));
}
return resultList;
}
}
基本上spring mvc已经给我们提供了足够的校验类型,如果不能满足项目需求,还可以使用正则表达式的方式,或者自定义注解的方式。
在 controller 的方法需要校验的参数后面必须跟 BindingResult,否则无法进行校验。但是这样会抛出异常,对用户而言不太友好!
2、拦截异常并统一处理
在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。
package com.demo;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 全局异常捕获
* @param req
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ModelMap handleException(Exception e) {
ModelMap modelMap = new ModelMap();
modelMap.addAttribute("msg", "后台异常捕获");
modelMap.addAttribute("Exception", e);
return modelMap;
}
}
@ExceptionHandler 拦截了异常,我们可以通过该注解实现自定义异常处理。其中,@ExceptionHandler 配置的 value 指定需要拦截的异常类型,上面拦截了 Exception.class 这种异常。
网友评论