您好,登錄后才能下訂單哦!
這篇文章主要講解了“SpringBoot全局異常處理方式是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“SpringBoot全局異常處理方式是什么”吧!
為了讓客戶端能有一個(gè)更好的體驗(yàn),當(dāng)客戶端發(fā)送請求到服務(wù)端發(fā)生錯(cuò)誤時(shí)服務(wù)端應(yīng)該明確告訴客戶端錯(cuò)誤信息。
SpringBoot內(nèi)置的異常處理返回的界面太雜亂,不夠友好。我們需要將異常信息做封裝處理響應(yīng)給前端。本文介紹的為將錯(cuò)誤信息統(tǒng)一封裝成如下格式j(luò)son響應(yīng)給前端。
{ code:10001, message:xxxxx, request:GET url }
自定義異常類
package com.lin.missyou.exception; public class HttpException extends RuntimeException{ protected Integer code; protected Integer httpStatusCode; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public Integer getHttpStatusCode() { return httpStatusCode; } public void setHttpStatusCode(Integer httpStatusCode) { this.httpStatusCode = httpStatusCode; } }
package com.lin.missyou.exception; public class NotFoundException extends HttpException{ public NotFoundException(int code){ this.httpStatusCode = 404; this.code = code; } }
package com.lin.missyou.exception; public class ForbiddenException extends HttpException{ public ForbiddenException(int code){ this.httpStatusCode = 403; this.code = code; } }
創(chuàng)建一個(gè)用于封裝異常信息的類UnifyResponse
package com.lin.missyou.core; public class UnifyResponse { private int code; private String message; private String request; public int getCode() { return code; } public String getMessage() { return message; } public String getRequest() { return request; } public UnifyResponse(int code, String message, String request) { this.code = code; this.message = message; this.request = request; } }
將異常信息寫在配置文件exception-code.properties里
lin.codes[10000] = 通用異常 lin.codes[10001] = 通用參數(shù)錯(cuò)誤
自定義配置類管理配置文件
package com.lin.missyou.core.configuration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; @PropertySource(value="classpath:config/exception-code.properties") @ConfigurationProperties(prefix = "lin") @Component public class ExceptionCodeConfiguration { private Map<Integer,String> codes = new HashMap<>(); public Map<Integer, String> getCodes() { return codes; } public void setCodes(Map<Integer, String> codes) { this.codes = codes; } public String getMessage(int code) { String message = codes.get(code); return message; } }
創(chuàng)建一個(gè)全局異常處理類GlobalExceptionAdvice,用@ControllerAdvice標(biāo)明異常處理類。@ResponseStatus用于指定http狀態(tài)碼。
@ExceptionHandler標(biāo)明異常處理器,傳入?yún)?shù)指定當(dāng)前函數(shù)要處理哪種類型的異常。Springboot會(huì)幫我們把這些異常信息傳入到函數(shù)。第一個(gè)函數(shù)用于處理未知異常,不需要向前端提供詳細(xì)的錯(cuò)誤原因,只需提示統(tǒng)一的文本信息即可。
第二個(gè)函數(shù)用于處理已知異常,需要指明具體的錯(cuò)誤原因,需要根據(jù)Exception傳遞過來的信息靈活的定制httpStatusCode。ResponseEntity可以自定義很多屬性,包括可以設(shè)置httpheaders,httpbodys,httpStatus。
package com.lin.missyou.core; import com.lin.missyou.core.config.ExceptionCodeConfiguration; import com.lin.missyou.exception.HttpException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.ObjectError; 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 org.springframework.web.bind.annotation.ResponseStatus; import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import java.util.List; @ControllerAdvice public class GlobalExceptionAdvice { @Autowired ExceptionCodeConfiguration exceptionCodeConfiguration ; @ExceptionHandler(Exception.class) @ResponseBody @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public UnifyResponse handleException(HttpServletRequest req,Exception e){ String method = req.getMethod(); String requestUrl = req.getRequestURI(); System.out.println(e); UnifyResponse unifyResponse = new UnifyResponse(9999,"服務(wù)器錯(cuò)誤",method+" "+requestUrl); return unifyResponse; } @ExceptionHandler(HttpException.class) public ResponseEntity<UnifyResponse> handleHttpException(HttpServletRequest req, HttpException e){ String method = req.getMethod(); String requestUrl = req.getRequestURI(); System.out.println(e); UnifyResponse unifyResponse = new UnifyResponse(e.getCode(),exceptionCodeConfiguration.getMessage(e.getCode()),method+" "+requestUrl); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode()); ResponseEntity<UnifyResponse> responseEntity = new ResponseEntity(unifyResponse,httpHeaders,httpStatus); return responseEntity; } //參數(shù)校驗(yàn) @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public UnifyResponse handleBeanValidation(HttpServletRequest req, MethodArgumentNotValidException e){ String method = req.getMethod(); String requestUrl = req.getRequestURI(); List<ObjectError> errors = e.getBindingResult().getAllErrors(); String message = formatAllErrorMessages(errors); return new UnifyResponse(10001,message,method+" "+requestUrl); } private String formatAllErrorMessages(List<ObjectError> errors){ StringBuffer errorMsg = new StringBuffer(); errors.forEach(error -> errorMsg.append(error.getDefaultMessage()).append(";") ); return errorMsg.toString(); } @ExceptionHandler(ConstraintViolationException.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public UnifyResponse handleConstrainException(HttpServletRequest req, ConstraintViolationException e){ String method = req.getMethod(); String requestUrl = req.getRequestURI(); String message = e.getMessage(); return new UnifyResponse(10001,message,method+" "+requestUrl); } }
響應(yīng)信息可能會(huì)出現(xiàn)亂碼現(xiàn)象,修改配置文件編碼。在設(shè)置面板搜索File Encodings,Default encoding for properties files選擇UTF-8,勾選Transparent native-to-ascii conversion
項(xiàng)目結(jié)構(gòu):
1、自定義異常類 MyException.java
package com.gui.restful; /** * 自定義異常類 */ public class MyException extends RuntimeException{ private String code; private String msg; public MyException(String code,String msg){ this.code=code; this.msg=msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
2、控制器 MyController.java
package com.gui.restful; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; /** * controller拋出異常 */ @RestController public class MyController { @RequestMapping("hello") public String hello() throws Exception{ throw new MyException("101","系統(tǒng)異常"); } }
3、全局異常處理類 MyControllerAdvice
package com.gui.restful; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashMap; import java.util.Map; /** * 全局異常捕獲處理 */ @ControllerAdvice //controller增強(qiáng)器 public class MyControllerAdvice { @ResponseBody @ExceptionHandler(value=MyException.class) //處理的異常類型 public Map myExceptionHandler(MyException e){ Map<String,String> map=new HashMap<>(); map.put("code",e.getCode()); map.put("msg",e.getMsg()); return map; } }
4、運(yùn)行結(jié)果
啟動(dòng)應(yīng)用,訪問 http://localhost:8080/hello,出現(xiàn)以下結(jié)果,說明自定義異常被成功攔截
1、自定義異常類 MyException.java(同上)
2、控制器 MyController.java(同上)
3、全局異常處理類 MyControllerAdvice
package com.gui.restful; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import java.util.HashMap; import java.util.Map; /** * 全局異常捕獲處理 */ @ControllerAdvice //controller增強(qiáng)器 public class MyControllerAdvice { @ExceptionHandler(value=MyException.class) //處理的異常類型 public ModelAndView myExceptionHandler(MyException e){ ModelAndView modelAndView=new ModelAndView(); modelAndView.setViewName("error"); modelAndView.addObject("code",e.getCode()); modelAndView.addObject("msg",e.getMsg()); return modelAndView; } }
4、頁面渲染 error.ftl(用freemarker渲染)
pom.xml中引入freemarker依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
error.ftl
<!DOCTYPE> <html> <head> <title>錯(cuò)誤頁面</title> </head> <body> <h2>code:$[code]</h2> <h2>msg:${msg}</h2> </body> </html>
5、運(yùn)行結(jié)果
啟動(dòng)應(yīng)用,訪問 http://localhost:8080/hello,出現(xiàn)以下結(jié)果,說明自定義異常被成功攔截
感謝各位的閱讀,以上就是“SpringBoot全局異常處理方式是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對SpringBoot全局異常處理方式是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。