溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SpringBoot全局異常處理方式是什么

發(fā)布時(shí)間:2021-11-19 16:27:25 來源:億速云 閱讀:120 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“SpringBoot全局異常處理方式是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“SpringBoot全局異常處理方式是什么”吧!

SpringBoot全局異常處理

為了讓客戶端能有一個(gè)更好的體驗(yàn),當(dāng)客戶端發(fā)送請求到服務(wù)端發(fā)生錯(cuò)誤時(shí)服務(wù)端應(yīng)該明確告訴客戶端錯(cuò)誤信息。

SpringBoot全局異常處理方式是什么

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

springboot全局異常處理——@ControllerAdvice+ExceptionHandler

一、全局捕獲異常后,返回json給瀏覽器

項(xiàng)目結(jié)構(gòu):

SpringBoot全局異常處理方式是什么

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é)果,說明自定義異常被成功攔截

SpringBoot全局異常處理方式是什么

二、全局捕獲異常后,返回頁面給瀏覽器

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全局異常處理方式是什么

感謝各位的閱讀,以上就是“SpringBoot全局異常處理方式是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對SpringBoot全局異常處理方式是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(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)容。

AI