1. 程式人生 > >springboot 統一引數校驗配置

springboot 統一引數校驗配置

採坑

1號坑: 引數長度校驗時特殊字元經過url編碼時 1位變3位長度校驗會出現問題

思路

通過全域性異常處理器 來攔截引數校驗的異常 進行統一的引數校驗處理

步驟

匯入jar包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

驗證配置

package com.***.config;

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

/**
 * 全域性驗證配置
 *
 * @author imsjw
 * @Date Created in 15:42 2018/6/7
 */
@Configuration
public class ValidatorConfig {

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        /**設定validator模式為快速失敗返回*/
        postProcessor.setValidator(validator());
        return postProcessor;
    }

    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure()
                .addProperty("hibernate.validator.fail_fast", "true")
                .buildValidatorFactory();
        Validator validator = validatorFactory.getValidator();
        return validator;
    }

}

全域性異常處理

package com.***.config;

import com.***.base.BaseException;
import com.***.entity.ExceptionResult;
import com.***.util.UUIDUtil;
import jdk.management.resource.internal.inst.StaticInstrumentation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ValidationException;

/**
 * 全域性異常處理器
 *
 * @author imsjw
 * @Date Created in 10:45 2018/6/6
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 基本異常處理
     *
     * @param e
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ExceptionResult basicExceptionHandling(Exception e) {
        ExceptionResult result = new ExceptionResult(UUIDUtil.random(), false, "未知錯誤");
        printfExceptionInfo(e, result);
        return result;
    }

    @ResponseBody
    @ExceptionHandler(value = BaseException.class)
    public ExceptionResult baseExceptionHandling(BaseException e) {
        ExceptionResult result = new ExceptionResult(UUIDUtil.random(), false, "錯誤");
        printfExceptionInfo(e.getException(), result, e.getMessage());
        return result;
    }

    /**
     * 用於Controller引數校驗錯誤的統一處理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = ValidationException.class)
    public ExceptionResult validationExceptionHandling(ValidationException e) {
        ExceptionResult result = new ExceptionResult(UUIDUtil.random(), false, "引數不符合規則");
        printfExceptionInfo(e, result);
        return result;
    }


    private void printfExceptionInfo(Exception e, ExceptionResult result) {
        if (result.getData() != null) {
            printfExceptionInfo(e, result, result.getData().toString());
        } else {
            printfExceptionInfo(e, result, null);
        }
    }

    private void printfExceptionInfo(Exception e, ExceptionResult result, String title) {
        StringBuffer strBuf = new StringBuffer();
        strBuf.append("\r\n**********異常資訊開始**********\r\n");
        strBuf.append("ID:");
        strBuf.append(result.getId());
        strBuf.append(" 標題:");
        strBuf.append(title);
        strBuf.append("\r\n");
        if (e != null) {
            strBuf.append(e.getMessage());
            strBuf.append("\r\n");
            strBuf.append(e.toString());
            strBuf.append("\r\n");
            StackTraceElement[] stackTrace = e.getStackTrace();
            if (stackTrace != null) {
                for (StackTraceElement t : stackTrace) {
                    strBuf.append(t.toString());
                    strBuf.append("\r\n");
                }
            }
        }
        strBuf.append("**********異常資訊結束**********");
        strBuf.append("\r\n");
        log.error(strBuf.toString());
    }

}

以上為核心程式碼,以下為其與部分程式碼

BaseException

package com.***.base;

import java.io.Serializable;

/**
 * 核心實體類
 *
 * @author imsjw
 * @Date Created in 22:13 2018/6/14
 */
public abstract class BaseEntity implements Serializable {

    /**
     * 返回一個可以返回給使用者的資料結構
     *
     * @return Object
     */
    public abstract <T extends BaseEntity> T toResult();

}

ExceptionResult

package com.***.entity;

/**
 * 返回給使用者的異常資訊結果
 *
 * @author imsjw
 * @Date Created in 16:07 2018/6/7
 */
public class ExceptionResult extends Result {

    /**
     * 異常的唯一表示符
     */
    private String id;

    public ExceptionResult() {

    }

    public ExceptionResult(String id, boolean state, Object data) {
        super(state,data);
        this.id = id;
    }


    @Override
    public String toString() {
        return "ExceptionResult{" +
                "id='" + id + '\'' +
                '}';
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

Result

package com.***.entity;

import com.***.base.BaseEntity;

import java.util.ArrayList;
import java.util.List;

/**
 * 提供的網路介面返回的基類
 *
 * @author imsjw
 * @Date Created in 20:37 2018/6/5
 */
public class Result {

    private boolean state;
    private Object data;

    public Result() {
    }

    public Result(boolean state) {
        this.state = state;
    }

    public Result(boolean state, Object data) {
        this.state = state;
        if (data != null) {
            if (data instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) data;
                this.data = baseEntity.toResult();
                return;
            }
            if (data instanceof List) {
                List list = (List) data;
                if ((!list.isEmpty()) && list.get(0) instanceof BaseEntity) {
                    List<BaseEntity> baseEntities = new ArrayList<>();
                    for (int i = 0; i < list.size(); i++) {
                        BaseEntity baseEntity = (BaseEntity) list.get(i);
                        baseEntities.add(baseEntity.toResult());
                    }
                    this.data = baseEntities;
                    return;
                }
            }
        }
        this.data = data;
    }

    @Override
    public String toString() {
        return "Result{" +
                "state=" + state +
                ", data=" + data +
                '}';
    }

    public boolean isState() {
        return state;
    }

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

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

BaseEntity

package com.***.base;

import java.io.Serializable;

/**
 * 核心實體類
 *
 * @author imsjw
 * @Date Created in 22:13 2018/6/14
 */
public abstract class BaseEntity implements Serializable {

    /**
     * 返回一個可以返回給使用者的資料結構
     *
     * @return Object
     */
    public abstract <T extends BaseEntity> T toResult();

}