Controller層方法經常會接收前端傳回的資料,并進行參數校驗。
可以采取注解式的參數校驗方法,這樣就不需要在每個controller方法裡都手寫參數校驗代碼。
思路
- 使用 Hibernate validator 參數校驗
- 對實體類進行注解,将校驗代碼配置成注解
- 不同的Controller方法可能有不同的校驗需求,可采用分組校驗的方法解決
- 特殊的校驗需求,可以使用自定義校驗注解的方式處理
實作
-
建立校驗分組
校驗分組可實作對不同校驗需求進行不同适配。隻需要建立接口即可。
package com.zp.haveplace.validator.group.admin;
/**
* 校驗分組
* 管理者登入時的Controller校驗
* @author zp
* @date 2018/4/20
*/
public interface LoginValidatorGroup {
}
package com.zp.haveplace.validator.group.admin;
/**
* 校驗分組
* 修改管理者資訊時的Controller校驗
* @author zp
* @date 2018/4/20
*/
public interface UpdateAdminValidatorGroup {
}
- 實體類中對需要校驗的字段進行注解
package com.zp.haveplace.entity;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.FieldFill;
import com.baomidou.mybatisplus.enums.FieldStrategy;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.zp.haveplace.util.TimeUtils;
import com.zp.haveplace.validator.group.admin.AddAdminValidatorGroup;
import com.zp.haveplace.validator.group.admin.LoginValidatorGroup;
import com.zp.haveplace.validator.group.admin.UpdateAdminValidatorGroup;
import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.constraints.Min;
import java.util.Date;
/**
* 背景管理者資訊
* "password",isDeleted","gmtCreate","gmtModified"字段不輸出
*/
@JsonIgnoreProperties({"password","isDeleted","gmtCreate","gmtModified"})
@TableName("_admin")
public class Admin {
@NotEmpty(message = "被修改管理者id不能為空",groups = {UpdateAdminValidatorGroup.class})
@Min(value = 1,message = "id必須大于0",groups = {UpdateAdminValidatorGroup.class})
private Integer adminId;
// 登入校驗,添加校驗
@NotEmpty(message = "賬号不能為空",groups = {LoginValidatorGroup.class,AddAdminValidatorGroup.class})
private String account;
// 登入校驗,添加校驗
@NotEmpty(message = "密碼不能為空",groups = {LoginValidatorGroup.class,AddAdminValidatorGroup.class})
private String password;
private Integer role;
private String phone;
private String comment;
private Integer isDeleted;
private Date gmtCreate;
private Date gmtModified;
//......get/set方法
}
其中,@JsonIgnoreProperties注解是用于實體類包裝傳回為JSON時需要忽略的字段;message意思是校驗不通過時傳回的資訊,資訊除了寫死以外,還可以通過配置檔案擷取,我采取了寫死;groups是校驗分組。
- Controller使用校驗
package com.zp.haveplace.web;
import com.zp.haveplace.annotation.LoginRequired;
import com.zp.haveplace.annotation.RoleRequired;
import com.zp.haveplace.bean.PageBean;
import com.zp.haveplace.bean.ResponseBean;
import com.zp.haveplace.common.RoleConst;
import com.zp.haveplace.common.SessionConstant;
import com.zp.haveplace.entity.Admin;
import com.zp.haveplace.service.AdminService;
import com.zp.haveplace.bean.LoggerBean;
import com.zp.haveplace.util.TimeUtils;
import com.zp.haveplace.validator.group.admin.LoginValidatorGroup;
import com.zp.haveplace.validator.group.admin.UpdateAdminValidatorGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.security.acl.Group;
import java.util.EnumSet;
import java.util.List;
import org.springframework.validation.BindingResult;
/**
* 管理者控制器
*
* @author zp
* @date 2018/4/21
*/
@Controller
@RequestMapping("/admin")
public class AdminController{
// 使用者登入方法
@RequestMapping(value = "/login",method = RequestMethod.POST)
@ResponseBody
public ResponseBean login(@Validated(value = {LoginValidatorGroup.class}) Admin loginAdmin,
BindingResult bindingResult,
HttpServletRequest request)throws Exception{
//需要校驗的參數必須使用@Validated注解,并在此注解後增加BindingResult參數
//@Validated需配置校驗分組
//BindingResult類用于存儲校驗結果
//檢查校驗結果
if(bindingResult.hasErrors()){
String errorInfo = "";
List<FieldError> errors = bindingResult.getFieldErrors();//擷取字段參數不合法的錯誤集合
for(FieldError error : errors){
errorInfo = errorInfo + "[" + error.getField() + " " + error.getDefaultMessage() + "]";
}
return new ResponseBean().setExceptionResponse(errorInfo);//傳回校驗錯誤
}
//.....業務邏輯代碼
return new ResponseBean().setSuccessMessage("登入成功");
}
}
對校驗結果的檢查,可以采用AOP方式實作,徹底抛棄controller寫死。具體實作請參考:
[Spring] Web層使用AOP方式進行參數校驗-
自定義校驗
百度有很多
參考
部分源碼及思路來自:
優雅的SSM(Spring+SpringMVC+Mybatis)架構 Hibernate Validator注解大全 [SpringMVC] Web層傳回值包裝JSON