天天看點

[SpringMVC] Web層注解式參數校驗

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