javascript
springboot怎么返回404_深度分析:SpringBoot异常捕获与封装处理,看完你学会了吗?...
簡介
日常開發(fā)過程中,難免有的程序會因?yàn)槟承┰驋伋霎惓?#xff0c;而這些異常一般都是利用try ,catch的方式處理異?;蛘遲hrow,throws的方式拋出異常不管。這種方法對于程序員來說處理也比較麻煩,對客戶來說也不太友好,所以我們希望既能方便程序員編寫代碼,不用過多的自己去處理各種異常編寫重復(fù)的代碼又能提升用戶的體驗(yàn),這時(shí)候全局異常處理就顯得很重要也很便捷了,是一種不錯(cuò)的選擇。
全網(wǎng)獨(dú)家Spring/Cloud/MVC/Boot,腦圖+面試+進(jìn)階,就問你服不服??zhuanlan.zhihu.com一、 全局異常捕獲與處理
Springboot對于異常的處理做了不錯(cuò)的支持,它提供了兩個(gè)可用的注解。
@ControllerAdvice:用來開啟全局的異常捕獲
@ExceptionHandler:說明捕獲哪些異常,對哪些異常進(jìn)行處理。
@ControllerAdvice public class MyExceptionHandler {@ExceptionHandler(value =Exception.class)public String exceptionHandler(Exception e){System.out.println("發(fā)生了一個(gè)異常"+e);return e.getMessage();} }上面這段代碼的意思是,只要是代碼運(yùn)行過程中有異常就會進(jìn)行捕獲,并輸出出這個(gè)異常。然后我們隨便編寫一個(gè)會發(fā)生異常的代碼,測試出來的異常是這樣的。
這對于前后端分離來說并不好,前后端分離之后唯一的交互就是json了,我們也希望將后端的異常變成json返回給前端處理,所以就需要統(tǒng)一結(jié)果返回和統(tǒng)一異常處理。
二、統(tǒng)一結(jié)果返回與統(tǒng)一異常
Result類:封裝返回結(jié)果。
public class Result<T> {private Integer code;//狀態(tài)碼private String message;//提示消息private T data;//數(shù)據(jù)public Result() {}/*** @param code 響應(yīng)碼* @param message 響應(yīng)信息*/public Result(Integer code, String message) {this.code = code;this.message = message;}/*** @param code 響應(yīng)碼* @param message 響應(yīng)信息* @param data 數(shù)據(jù)*/public Result(Integer code, String message, T data) {this.code = code;this.message = message;this.data = data;}/*** @param resultEnum 自定義枚舉類,包含 code 和 message*/public Result(ResultEnum resultEnum) {this.code = resultEnum.getCode();this.message = resultEnum.getMessage();}/*** @param resultEnum 自定義枚舉類,包含 code 和 message* @param data 數(shù)據(jù)*/public Result(ResultEnum resultEnum, T data) {this.code = resultEnum.getCode();this.message = resultEnum.getMessage();this.data = data;}/*** 自定義異常返回的結(jié)果* @param definitionException 自定義異常處理類* @return 返回自定義異常*/public static Result<Object> defineError(DefinitionException definitionException) {return new Result<>(definitionException.getErrorCode(), definitionException.getErrorMessage());}/*** 其他異常處理方法返回的結(jié)果* @param resultEnum 自定義枚舉類,包含 code 和 message* @return 返回其他異常*/public static Result<Object> otherError(ResultEnum resultEnum) {return new Result<>(resultEnum);}//這里寫get和set方法 }注意:其中省略了get,set方法。
ResultEnum:自定義枚舉類。
public enum ResultEnum {// 數(shù)據(jù)操作定義SUCCESS(200, "成功"),TIME_OUT(130, "訪問超時(shí)"),NO_PERMISSION(403, "拒絕訪問"),NO_AUTH(401, "未經(jīng)授權(quán)訪問"),NOT_FOUND(404, "無法找到資源"),METHOD_NOT_ALLOWED(405, "不支持當(dāng)前請求方法"),SERVER_ERROR(500, " 服務(wù)器運(yùn)行異常"),NOT_PARAM(10001, "參數(shù)不能為空"),NOT_EXIST_USER_OR_ERROR_PASSWORD(10002, "該用戶不存在或密碼錯(cuò)誤"),NOT_PARAM_USER_OR_ERROR_PASSWORD(10003, "用戶名或密碼為空");;/*** 響應(yīng)碼*/private final Integer code;/*** 響應(yīng)信息*/private final String message;/*** 有參構(gòu)造* @param code 響應(yīng)碼* @param message 響應(yīng)信息*/ResultEnum(Integer code, String message) {this.code = code;this.message = message;}public Integer getCode() {return code;}public String getMessage() {return message;} }注意:枚舉類中定義了常見的錯(cuò)誤碼以及錯(cuò)誤的提示信息。這里我們就定義好了統(tǒng)一的結(jié)果返回,其中里面的靜態(tài)方法是用來當(dāng)程序異常的時(shí)候轉(zhuǎn)換成異常返回規(guī)定的格式。
DefinitionException:自定義異常處理類。
//@ControllerAdvice+@ResponseBody,開啟全局的異常捕獲,返回JSON @RestControllerAdvice public class GlobalExceptionHandler {/*** 處理自定義異常* @return Result* @ExceptionHandler 說明捕獲哪些異常,對那些異常進(jìn)行處理。*/@ExceptionHandler(value = DefinitionException.class)public Result<Object> customExceptionHandler(DefinitionException e) {return Result.defineError(e);}/*** 處理其他異常* @return Result*/@ExceptionHandler(value = Exception.class)public Result<Object> exceptionHandler(Exception e) {return Result.otherError(ErrorEnum.INTERNAL_SERVER_ERROR);} }說明:將對象解析成json,是為了方便前后端的交互。
三、代碼測試與結(jié)果
測試類
ResultController:測試的controller類
@RestController public class ResultController {//獲取學(xué)生信息@GetMapping("/student")public Result<Student> getStudent() {Student student = new Student();student.setId(1);student.setAge(18);student.setName("XuWwei")return new Result<>(ResultEnum.SUCCESS, student);}//自定義異常處理@RequestMapping("/getDeException")public Result<Object> DeException() {throw new DefinitionException(400, "我出錯(cuò)了");}//其他異常處理@RequestMapping("/getException")public Result Exception(){Result result = new Result();int a=1/0;return result;}Student:學(xué)生類
public class Student {/*** 唯一標(biāo)識id*/private Integer id;/*** 姓名*/private String name;/*** 年齡*/private Integer age; }注意:其中省略了get,set方法。
測試結(jié)果
啟動項(xiàng)目,一個(gè)一個(gè)測試
可以看到數(shù)據(jù)是正常返回json,沒有異常。
可以看到這個(gè)自定義的異常被捕獲到了,并且返回了一個(gè)json。
可以看到這個(gè)異常被捕獲到了,并且返回了一個(gè)json。
注意:這種方法是不能處理404異常的,捕獲不到。
四、404異常特殊處理
1、修改配置文件
? 默認(rèn)情況下,SpringBoot是不會拋出404異常的,所以**@ControllerAdvice**也不能捕獲到404異常。我們可以通過配置文件來讓這個(gè)注解能捕獲到404異常,在application.properties中添加以下配置:
#當(dāng)發(fā)現(xiàn)404異常時(shí)直接拋出異常 spring.mvc.throw-exception-if-no-handler-found=true #關(guān)閉默認(rèn)的靜態(tài)資源路徑映射,這樣404不會跳轉(zhuǎn)到默認(rèn)的頁面 spring.resources.add-mappings=false但是關(guān)閉默認(rèn)的靜態(tài)資源路徑映射會讓靜態(tài)資源訪問出現(xiàn)問題,也就是不適合前后端一體的情況。
但是我們可以手動配置靜態(tài)資源路徑映射,就能正常訪問靜態(tài)資源了。
@Configuration public class ResourceConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//可以訪問localhost:8080/static/images/image.jpgregistry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");} }2、修改error跳轉(zhuǎn)路徑
? 關(guān)閉默認(rèn)的靜態(tài)資源路徑映射顯然不太合理,可能會導(dǎo)致其他的錯(cuò)誤發(fā)生,所以也可以通過修改默認(rèn)錯(cuò)誤頁面的跳轉(zhuǎn)路徑來達(dá)到我們的目的。
在GlobalExceptionHandler類中添加NotFoundExceptionHandler類,這個(gè)類繼承了ErrorController,可以重寫error的跳轉(zhuǎn)路徑
//處理404NotFoundException @Controller class NotFoundExceptionHandler implements ErrorController {//設(shè)置錯(cuò)誤頁面路徑@Overridepublic String getErrorPath() {return "/error";}//當(dāng)訪問error路徑時(shí),返回一個(gè)封裝的異常的Json@RequestMapping("/error")@ResponseBodypublic Result<Object> error() {return Result.otherError(ResultEnum.NOT_FOUND);} }五、拓展異常類
? GlobalExceptionHandler的exceptionHandler方法將所有的異常統(tǒng)一返回500系統(tǒng)錯(cuò)誤,這不符合我們的設(shè)想,所以我們可以通過判斷異常的類型,來返回不同的值。
將exceptionHandler改成以下代碼:
/*** 處理其他異常* @return Result*/ @ExceptionHandler(value = Exception.class) public Result<Object> exceptionHandler(Exception e) {if (e instanceof NullPointerException){//捕獲空指針異常return Result.otherError(ResultEnum.NOT_PARAM);}else if (e instanceof IllegalAccessException){//非法訪問異常return Result.otherError(ResultEnum.NO_PERMISSION);} else{return Result.otherError(ResultEnum.SERVER_ERROR);} }注意:更多異??梢酝ㄟ^else if來細(xì)分。
六、總結(jié)
?springboot的異常處理,需要通過@ControllerAdvice注解以及 @ExceptionHandler注解,來攔截所有的異常,并通過一個(gè)封裝返回值返回。但是,這兩個(gè)注解無法捕獲404NotFound異常,因?yàn)镾pringBoot默認(rèn)是不會拋出404異常的,所以要通過繼承ErrorController來修改404異常的跳轉(zhuǎn)路徑,達(dá)到捕獲404異常的目的。
總結(jié)
以上是生活随笔為你收集整理的springboot怎么返回404_深度分析:SpringBoot异常捕获与封装处理,看完你学会了吗?...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从西安北站到西安朗程优佳酒店(高铁北站北
- 下一篇: 丰台区东高地附近有公证处吗