Spring Boot 全域性異常處理 與 Hibernate Validator校驗框架整合
阿新 • • 發佈:2018-11-28
Hibernate Validator校驗框架的使用
Spring boot已經集成了hibernate-validator,不需要引入maven,其他框架也可以自己引入:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.3.5.Final</version> </dependency>
註解詳解(需要校驗的model類)
import io.swagger.models.Model; import org.hibernate.validator.constraints.*; import javax.validation.Valid; import javax.validation.constraints.*; import java.math.BigDecimal; import java.util.List; /** * @author 向振華 * @date 2018/11/21 09:59 */ public class Eg { /**空檢查*/ //驗證物件是否為null @Null(message = "")//message為異常類中的message private Model model1; //檢查基本型別是否為空 @NotNull(message = "") private Integer integer; //檢查約束字串是不是Null還有被Trim的長度是否大於0,且會去掉前後空格 @NotBlank(message = "") private String string; //檢查集合是否為NULL或者是EMPTY @NotEmpty(message = "") private List<String> stringList; /**Booelan檢查*/ //驗證 Boolean 物件是否為 true @AssertTrue(message = "") private Boolean tBoolean; //驗證 Boolean 物件是否為 false @AssertFalse(message = "") private Boolean fBoolean; /**長度檢查*/ //驗證物件(Array,Collection,Map,String)長度是否在給定的範圍之內 @Size(min = 1, max = 100, message = "範圍1~100!") private List<String> stringLists; //驗證字串長度是否在指定範圍 @Length(min=1, max=20, message = "範圍1~20") private String stringl; /**日期檢查*/ //驗證 Date 和 Calendar 物件是否在當前時間之前 @Past() private java.util.Date date1; //驗證 Date 和 Calendar 物件是否在當前時間之後 @Future() private java.util.Date date2; /**字串正則檢查*/ //驗證 String 物件是否符合正則表示式的規則 @Pattern(regexp = "[1][3456789]\\d{9}", message = "手機號格式不正確") private String mobile; /**數值檢查*/ //建議使用在Stirng,Integer型別,不建議使用在int型別上,因為表單值為“”時無法轉換為int,但可以轉換為Stirng為"",Integer為null //驗證 Number 和 String 物件是否大等於指定的值 @Min(10) private Integer integer1; //驗證 Number 和 String 物件是否小等於指定的值 @Max(20) private Integer integer2; //被標註的值必須不大於約束中指定的最大值. 這個約束的引數是一個通過BigDecimal定義的最大值的字串表示.小數存在精度 @DecimalMax("10.1") private BigDecimal bigDecimal1; //被標註的值必須不小於約束中指定的最小值. 這個約束的引數是一個通過BigDecimal定義的最小值的字串表示.小數存在精度 @DecimalMin("20.2") private BigDecimal bigDecimal2; //驗證字串是否是符合指定格式的數字,interger指定整數精度,fraction指定小數精度。 @Digits(integer= 1,fraction= 2) private Integer integerh; //驗證值是否在指定的範圍 @Range(min=10000,max=50000) private BigDecimal wage; //遞迴的對關聯物件進行校驗, 如果關聯物件是個集合或者陣列,那麼對其中的元素進行遞迴校驗,如果是一個map,則對其中的值部分進行校驗.(是否進行遞迴驗證) @Valid //新增其他註解校驗 private List<Integer> integers; //信用卡驗證 @CreditCardNumber //驗證是否是郵件地址,如果為null,不進行驗證,算通過驗證。 @Email private String mailbox; // @ScriptAssert(lang= ,script=, alias=) // @URL(protocol=,host=, port=,regexp=, flags=) }
需要在Controller方法引數前面加@Validated使校驗框架生效
@Override
public ResponseMessage send(@RequestBody @Validated Eg eg) {
return sendService.send(eg);
}
返回值類 (用於返回給前端固定格式的值)
public class ResponseMessage<T> implements Serializable { /** * 1:成功 -1:失敗 */ private int code; /** * 資訊 */ private String msg; /** * 資料 */ private T data; }
全域性異常捕獲處理
/**
* 全域性異常捕獲處理
* @author 向振華
* @date 2018/11/21 10:37
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Log LOG = LogFactory.getLog(GlobalExceptionHandler.class);
/**
* 所有驗證框架異常捕獲處理
* @return
*/
@ResponseBody
@ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class})
public Object validationExceptionHandler(Exception exception) {
BindingResult bindResult = null;
if (exception instanceof BindException) {
bindResult = ((BindException) exception).getBindingResult();
} else if (exception instanceof MethodArgumentNotValidException) {
bindResult = ((MethodArgumentNotValidException) exception).getBindingResult();
}
String msg;
if (bindResult != null && bindResult.hasErrors()) {
msg = bindResult.getAllErrors().get(0).getDefaultMessage();
if (msg.contains("NumberFormatException")) {
msg = "引數型別錯誤!";
}
}else {
msg = "系統繁忙,請稍後重試...";
}
return new ResponseMessage(-1, msg);
}
/**
* 業務異常
* @param exception
* @return
*/
@ResponseBody
@ExceptionHandler(value = BusinessException.class)
public Object allBusinessExceptionHandler(BusinessException exception) {
return new ResponseMessage(-1, exception.getMessage());
}
/**
* 未知的異常捕獲處理
* @param exception
* @return
*/
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Object allUnknowExceptionHandler(HttpServletRequest request, Exception exception) {
String error = logError(request, exception);
//可以傳送郵件通知開發
return new ResponseMessage(-1, "系統繁忙,請稍後重試!");
}
private String logError(HttpServletRequest request, Exception exception) {
LOG.error("發生未知異常:", exception);
StringWriter sw = new StringWriter();
sw.append(String.format("Date:{%s};\n", DateUtil.dateToString(new Date())));
sw.append(String.format("url:{%s}產生錯誤;\n", request.getRequestURI()));
sw.append(String.format("請求IP:{%s};\n", request.getRemoteAddr()));
sw.append(String.format("type:{%s};\n", request.getMethod()));
sw.append(String.format("請求引數:{%s};\n", JSONObject.toJSONString(request.getParameterMap())));
exception.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
}