正常來講一個系統確定有不少業務異常。而這些業務異常的信息如何返回給前臺呈現給用戶。好比用戶的某些操做不被容許,須要給用戶提示。java
Spring 提供了@ControllerAdvice這個註解,這個註解能夠實現全局異常處理,全局數據綁定,全局數據預處理,這裏主要說下使用這個註解實現全局異常處理。git
1.定義咱們本身的業務異常ErrorCodeExceptiongithub
package com.nijunyang.exception.exception; /** * Description: * Created by nijunyang on 2019/12/20 9:36 */ public class ErrorCodeException extends RuntimeException { private int code; /** * 用於填充資源文件中佔位符 */ private Object[] args; public ErrorCodeException(int code, Object... args) { this.code = code; this.args = args; } public int getCode() { return code; } public Object[] getArgs() { return args; } }
2.編寫統一異常處理器RestExceptionHandler,使用@ControllerAdvice註解修飾,在異常處理器編寫針對某個異常的處理方法,使用@ExceptionHandler註解指向某個指定異常。當代碼中拋了該異常就會進入此方法執行,從而返回咱們處理後的信息給請求者。web
3.資源文件放置提示信息,根據錯誤碼去匹配提示信息。spring
package com.nijunyang.exception.handler; import com.nijunyang.exception.exception.ErrorCodeException; import com.nijunyang.exception.model.RestErrorResponse; import com.nijunyang.exception.model.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import javax.annotation.Resource; import java.io.File; import java.io.IOException; import java.util.Locale; /** * Description: 控制層統一異常處理 * Created by nijunyang on 2019/12/20 9:33 */ @ControllerAdvice public class RestExceptionHandler { @Autowired private MessageSource messageSource; //locale能夠處理國際化資源文件,不一樣的語言 @ExceptionHandler(value = ErrorCodeException.class) public final ResponseEntity<RestErrorResponse> handleBadRequestException(ErrorCodeException errorCodeException, Locale locale) { String message = messageSource.getMessage(String.valueOf(errorCodeException.getCode()), errorCodeException.getArgs(), locale); RestErrorResponse restErrorResponse = new RestErrorResponse(Status.FAILED, errorCodeException.getCode(), message); return new ResponseEntity<>(restErrorResponse, HttpStatus.OK); } }
4.配置文件指向資源文件位置(spring.messages.basename=xxx)springboot
spring.messages.basename指向資源的前綴名字就好了,後面的國家語言標誌不須要,Locale會根據系統的語言去識別,資源文件須要配置一個默認的(messages.properties),否則啓動的時候可能沒法正常注入資源,由於默認的是去加載不帶國家語言標誌的文件。app
固然前綴隨便配置什麼均可以 只要再springboot的配置文件spring.messages.basename的路徑配置正確就行,就像這樣子也是能夠的spring-boot
5.控制層模擬異常拋出:this
package com.nijunyang.exception.controller; import com.nijunyang.exception.exception.ErrorCodeException; import com.nijunyang.exception.model.ErrorCode; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Description: * Created by nijunyang on 2019/12/20 9:58 */ @RestController @RequestMapping("/error") public class Controller { @GetMapping("/file") public ResponseEntity test() { //模擬文件不存在 String path = "a/b/c/d.txt"; throw new ErrorCodeException(ErrorCode.FILE_DOES_NOT_EXIST_51001, path); } }
6.前臺調用結果spa
z/b/c/d.txt就去填充了資源文件中的佔位符
錯誤碼:
package com.nijunyang.exception.model; /** * Description: * Created by nijunyang on 2020/1/20 20:28 */ public final class ErrorCode { public static int FILE_DOES_NOT_EXIST_51001 = 51001; }
結果狀態:
package com.nijunyang.exception.model; /** * Description: * Created by nijunyang on 2019/12/20 10:21 */ public enum Status { SUCCESS, FAILED }
異常統一結果返回對象
package com.nijunyang.exception.model; /** * Description: * Created by nijunyang on 2019/12/20 9:38 */ public class RestErrorResponse { private Status status; /** * 錯誤碼 */ private Integer errorCode; /** * 錯誤信息 */ private String errorMsg; public RestErrorResponse(Status status, Integer errorCode, String errorMsg) { this.errorCode = errorCode; this.errorMsg = errorMsg; this.status = status; } public Integer getErrorCode() { return errorCode; } public void setErrorCode(Integer errorCode) { this.errorCode = errorCode; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } public Status getStatus() { return status; } }
pom文件依賴:springBoot版本是2.1.7.RELEASE
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency> </dependencies>
完整代碼:https://github.com/bluedarkni/study.git ---->springboot--->exception項目