Spring Validationチェックフレームワーク@Validated注記通常チェック、パケットチェックの使用、グローバル例外プロセッサと組み合わせて使用します.

12435 ワード

注意:Sring Validation検証フレームワークパラメータの検証メカニズム@Validated(Spring) JSR-303仕様は、標準JSR-303の変種であり、javaxは@Valid(標準JSR-303仕様)を提供し、BindingResultに合わせてパラメータ検証結果を直接提供することができる.
    @ValidatedはBindingResultと協力して個人的に堅苦しいと感じ、処理テストをしなければ検査結果は制定された規則に合致しないデータしか検証できず、どのデータに異常が発生したかは検証できない.フロントエンドはあなたが返した異常情報を手に入れる必要があるので、処理しないで直接彼にあげることはできません.そうしないと、フロントエンドはあなたを切ります.グローバル例外プロセッサの組み合わせについては後述します.
注記の説明
   	    	  
@Null	    	        
@NotNull	    	       ,          0   
@NotBlank	   	       ,                0
@NotEmpty	   、  、  	         (       0、      0)


boolean  	    	  
@AssertTrue	  	  boolean     true
@AssertFalse	  	  boolean     false


    	    	  
@Min	    	         ,               
@Max	    	         ,               
@DecimalMin	    	         ,               
@DecimalMax	    	         ,               
@Digits(integer=,fraction=)	    	         ,interger      ,fraction      
@Range(min =,max = )	    、   	       min max   
@Length(min =,max = )	   	          min max   
@Size(min =,max = )	   、  、  	       min max   ,     、    


    	    	  
@Email	   	         Email  ,     regexp flag      email  
@Pattern	   	                  
@CreditCardNumber	    、   	              
@URL	   	         URL  

Springbootプロジェクトはデフォルトでベースパッケージをインポートしているので、別途パッケージを導く必要はなく、直接使用できます.
1.まずエンティティクラスを配置します.次に、作業中に機能テストを書くために使用します.今日は使用します.
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.hibernate.validator.constraints.Length;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

/**
 *        
 * 
 * @author XRJ
 * @email [email protected]
 * @date 2020-04-06 20:46:31
 */
@Data
@Valid
@TableName("hostconfiguration")
public class HostconfigurationEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 *   id
	 */
	@TableId
	@NotNull(groups = {Update.class})
	private int id;

	/**
	 *    ip
	 */
	@NotNull(groups = {Insert.class})
	@Pattern(groups = {Insert.class, Update.class, Select.class}, regexp = "((2[0-4]\\d|25[0-5]|1?[1-9]?\\d)\\.){3}(2[0-4]\\d|25[0-5]|1?[1-9]?\\d)", message = "      IP  ")
	private String localhostIp;

	/**
	 *      
	 */
	@NotBlank(groups = {Insert.class})
	@Pattern(groups = {Insert.class, Update.class}, regexp = "\\w{1,32}", message = "     [a-zA-Z0-9_]   ,      32 ")
	private String localhostUsername;

	/**
	 *      
	 */
	@NotBlank(groups = {Insert.class})
	@Length(groups = {Insert.class, Update.class}, min = 1, max = 32)
	private String localhostPassword;

	/**
	 *    
	 */
	@NotNull(groups = {Insert.class})
	private Integer localhostPort;

	/**
	 *        
	 */
	@NotBlank(groups = {Insert.class})
	private String localhostDirectory;

	/**
	 *   ,          
	 */
	@NotNull(groups = {Insert.class})
	private Integer numTime;

	/**
	 *     
	 */
	private Date createTime;
	/**
	 *     ,0  ,1  
	 */
	private Integer isSuccess;

}

上のgroups={Insert.class,Update.class,Select.class,Delete.class}はパケットチェックに属し,それぞれ添削チェックに対応する.コントロールレイヤで@Validated(Insert.class,Update.class,Select.class,Delete.class)を使用すると、対応するチェックが有効になります.
2.controller層コードは以下の通りである.
package cn.cm.filecompress.controller;

import cn.cm.filecompress.entity.HostconfigurationEntity;
import cn.cm.filecompress.service.HostconfigurationService;
import cn.cm.filecompress.tool.FileCompressTool;
import cn.cm.filecompress.tool.Result;
import com.jcraft.jsch.JSchException;
import org.apache.ibatis.annotations.Insert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 *        
 *
 * @author XRJ
 * @email [email protected]
 * @date 2020-04-06 20:46:31
 */
@RestController
@RequestMapping("/hostconfiguration")
public class HostconfigurationController {
    @Autowired
    private HostconfigurationService hostconfigurationService;

    @PostMapping(value = "/add",produces = "application/json;charset=UTF-8")
    public Result insert(@RequestBody @Validated(Insert.class) HostconfigurationEntity hostconf){
        return hostconfigurationService.insert(hostconf);
    }
}

グローバル異常捕獲器はまだ協力していません.まずpostmanでテストしてみます.次は私がシミュレーションしたデータです.
{
	"localhostPort":22,
	"localhostPassword":"",
	"localhostUsername":"",
	"localhostDirectory":"",
	"localhostIp":"192.156.124.90",
	"numTime":3
}

これは返された結果で、明らかに、異常情報全体を持ち帰って、どの属性が異常なのか分かりません.この時、グローバル異常プロセッサが来ました.
{"timestamp":1587890386937,"status":400,"error":"Bad Request","errors":[{"codes":["Length.hostconfigurationEntity.localhostPassword","Length.localhostPassword","Length.java.lang.String","Length"],"arguments":[{"codes":["hostconfigurationEntity.localhostPassword","localhostPassword"],"arguments":null,"defaultMessage":"localhostPassword","code":"localhostPassword"},32,1],"defaultMessage":"     1 32  ","objectName":"hostconfigurationEntity","field":"localhostPassword","rejectedValue":"","bindingFailure":false,"code":"Length"},{"codes":["NotBlank.hostconfigurationEntity.localhostPassword","NotBlank.localhostPassword","NotBlank.java.lang.String","NotBlank"],"arguments":[{"codes":["hostconfigurationEntity.localhostPassword","localhostPassword"],"arguments":null,"defaultMessage":"localhostPassword","code":"localhostPassword"}],"defaultMessage":"    ","objectName":"hostconfigurationEntity","field":"localhostPassword","rejectedValue":"","bindingFailure":false,"code":"NotBlank"},{"codes":["Pattern.hostconfigurationEntity.localhostUsername","Pattern.localhostUsername","Pattern.java.lang.String","Pattern"],"arguments":[{"codes":["hostconfigurationEntity.localhostUsername","localhostUsername"],"arguments":null,"defaultMessage":"localhostUsername","code":"localhostUsername"},[],{"defaultMessage":"\\w{1,32}","arguments":null,"codes":["\\w{1,32}"]}],"defaultMessage":"     [a-zA-Z0-9_]   ,      32 ","objectName":"hostconfigurationEntity","field":"localhostUsername","rejectedValue":"","bindingFailure":false,"code":"Pattern"},{"codes":["NotBlank.hostconfigurationEntity.localhostUsername","NotBlank.localhostUsername","NotBlank.java.lang.String","NotBlank"],"arguments":[{"codes":["hostconfigurationEntity.localhostUsername","localhostUsername"],"arguments":null,"defaultMessage":"localhostUsername","code":"localhostUsername"}],"defaultMessage":"    ","objectName":"hostconfigurationEntity","field":"localhostUsername","rejectedValue":"","bindingFailure":false,"code":"NotBlank"},{"codes":["NotBlank.hostconfigurationEntity.localhostDirectory","NotBlank.localhostDirectory","NotBlank.java.lang.String","NotBlank"],"arguments":[{"codes":["hostconfigurationEntity.localhostDirectory","localhostDirectory"],"arguments":null,"defaultMessage":"localhostDirectory","code":"localhostDirectory"}],"defaultMessage":"    ","objectName":"hostconfigurationEntity","field":"localhostDirectory","rejectedValue":"","bindingFailure":false,"code":"NotBlank"}],"message":"Validation failed for object='hostconfigurationEntity'. Error count: 5","path":"/compress/hostconfiguration/add"}

3.Validationチェックフレームワークはグローバル異常プロセッサと協力し、グローバル異常プロセッサコードは以下の通りである.
package cn.cm.filecompress.tool;

import com.alibaba.fastjson.JSONObject;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * description :        
 */
@ControllerAdvice
public class GlobalExceptionHandler {

//    private static final SystemLogger LOGGER = SystemLogger.getLogger(GlobalExceptionHandler.class);

    /**
     *       :Exception、SessionAttribute、@RequestAttribute、HttpServletRequest、HttpServletResponse、HttpSession
     *       : ModelAndView、@ResponseBody、ResponseEntity
     */
    @ExceptionHandler(Throwable.class)
    @ResponseBody
    public Result error(HttpServletResponse response, Exception e) {
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
//        LOGGER.error("      ", e);
        try {
            response.getWriter().print(JSONObject.toJSONString(Result.of(Code.SC_INTERNAL_SERVER_ERROR.getState(), Code.SC_INTERNAL_SERVER_ERROR.getDescription(), e.toString())));
        } catch (IOException exc) {
//            LOGGER.error("          ", exc);
        }
        return null;
//        return new Result<>(Code.SC_INTERNAL_SERVER_ERROR, e.toString());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public String handleMethodArgumentNotValid(HttpServletResponse response, Exception e) {
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
        BindingResult bindingResult = ex.getBindingResult();
        Map map = new HashMap<>();
        for (FieldError error : bindingResult.getFieldErrors()) {
            String field = error.getField();
            String msg = error.getDefaultMessage();
//            Object value = error.getRejectedValue();
//            map.put(field, String.format("{'value':'%s','errorMsg','%s'}", value, msg));
            map.put(field, msg);
        }
        try {
            response.getWriter().print(JSONObject.toJSONString(Result.of(Code.SC_PRECONDITION_FAILED.getState(), Code.SC_PRECONDITION_FAILED.getDescription(), map)));
        } catch (IOException exc) {
//            LOGGER.error("            ", exc);
        }
        return null;
//        return new Result<>(Code.SC_PRECONDITION_FAILED, map);
    }
}

前のデータを使用してインタフェースを再要求し、次のようにデータを返します.
{
    "code": 412,
    "data": {
        "localhostPassword": "     1 32  ",
        "localhostUsername": "     [a-zA-Z0-9_]   ,      32 ",
        "localhostDirectory": "    "
    },
    "message": "              "
}

これにより,要求体の中でどの属性に異常が発生したのかが明らかになる.これがグローバル異常プロセッサであり,会社の符号化要求が厳しいため,データ戻りフォーマットが統一されているため,カスタマイズできる.
Sring Validation検証フレームワークはこれで終わり、springcloudコアコンポーネントの構成と使用を個人のクラウドノートとして更新し、良いと思う仲間が注目しています.