日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
從零搭建后端框架——異常統(tǒng)一處理的三種方式

 [[327655]]

前言

項目在運(yùn)行時出現(xiàn)異常時,如若沒有對異常進(jìn)行捕獲并處理,就會出現(xiàn)如下頁面:

創(chuàng)新互聯(lián)建站是一家集網(wǎng)站建設(shè),洪江企業(yè)網(wǎng)站建設(shè),洪江品牌網(wǎng)站建設(shè),網(wǎng)站定制,洪江網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,洪江網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

這樣顯然對用戶是極其不友好的。

后端不應(yīng)該直接返回錯誤頁面,而應(yīng)返回統(tǒng)一的錯誤信息,比如:

  
  
  
  
  1. "code": 500, 
  2. "data": null, 
  3. "message": "服務(wù)異常,請稍后重試" 
  4. 復(fù)制代碼 

然后,前端根據(jù)返回的信息,顯示友好的提示頁面。

Spring提供了三種方式對異常統(tǒng)一處理:

  1. @ExceptionHandler
  2. 實現(xiàn)HandlerExceptionResolver接口
  3. @ControllerAdvice + @ExceptionHandler

下面我們來實際操作下。

具體實現(xiàn)

@ExceptionHandler

在【統(tǒng)一基類、接口、返回對象設(shè)計】這一篇文章中, 定義了Controller的基類BaseController,所以只要在BaseController中使用@ExceptionHandler處理異常, 其它Controller繼承BaseController即可。實現(xiàn)如下:

  
  
  
  
  1. @Slf4j 
  2. public abstract class BaseController { 
  3.  
  4. /** 
  5. * BusinessException 異常處理 
  6. */ 
  7. @ResponseBody 
  8. @ExceptionHandler(BusinessException.class) 
  9. public ApiResult businessExceptionHandler(BusinessException e) { 
  10. log.error(e.getMessage(), e); 
  11. // do something 
  12. return ApiResult.fail(e.getMessage()); 
  13.  
  14. /** 
  15. * Exception 異常處理 
  16. */ 
  17. @ResponseBody 
  18. @ExceptionHandler(Exception.class) 
  19. public ApiResult exceptionHandler(Exception e) { 
  20. log.error(e.getMessage(), e); 
  21. return ApiResult.fail("服務(wù)異常,請稍后重試"); 
  22. 復(fù)制代碼 

這里對異常BusinessException和Exception進(jìn)行了處理, BusinessException是約定的業(yè)務(wù)異常的基類,若是主動拋出一般都要求是BusinessException的子類,都會被businessExceptionHandler處理。 若是其它異常,可能是意想不到的異常,則會被exceptionHandler處理。

統(tǒng)一處理后,返回結(jié)果如下:

實現(xiàn)HandlerExceptionResolver接口

  
  
  
  
  1. @Slf4j 
  2. @Component 
  3. public class GlobalHandlerExceptionResolver implements HandlerExceptionResolver { 
  4.  
  5. @Override 
  6. public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) { 
  7. log.error(e.getMessage(), e); 
  8. ApiResult apiResult; 
  9. if (e instanceof BusinessException) { 
  10. BusinessException be = (BusinessException) e; 
  11. // do something 
  12. apiResult = ApiResult.fail(be.getMessage()); 
  13. } else { 
  14. apiResult = ApiResult.fail("服務(wù)異常,請稍后重試"); 
  15. WebUtils.writeJson(response, apiResult); 
  16. return null; 
  17. 復(fù)制代碼 

該方式需要實現(xiàn)HandlerExceptionResolver接口,然后將實現(xiàn)類注入到Spring容器中。

但第一種方式中,通過@ResponseBody注解,Spring就幫我們返回了json格式數(shù)據(jù),而這需要自己實現(xiàn)。

這里實現(xiàn)了工具類WebUtils,用于返回json數(shù)據(jù),如下:

  
  
  
  
  1. public class WebUtils { 
  2.  
  3. private static final Logger log = LoggerFactory.getLogger(WebUtils.class); 
  4.  
  5. private static Gson gson = new GsonBuilder().serializeNulls().create(); 
  6.  
  7. /** 
  8. * 返回json數(shù)據(jù) 
  9. * @param response 
  10. * @param object 
  11. */ 
  12. public static void writeJson(HttpServletResponse response, int status, Object object) { 
  13. response.setHeader("Content-Type", "application/json;charset=UTF-8"); 
  14. response.setContentType("application/json;charset=UTF-8"); 
  15. response.setStatus(status); 
  16. PrintWriter out = null; 
  17. try { 
  18. String data = object instanceof String ? (String) object : gson.toJson(object); 
  19. out = response.getWriter(); 
  20. out.print(data); 
  21. out.flush(); 
  22. } catch (Exception e) { 
  23. log.error(e.getMessage(), e); 
  24. } finally { 
  25. if (out != null) { 
  26. out.close(); 
  27.  
  28. /** 
  29. * 返回json數(shù)據(jù) 
  30. * @param response 
  31. * @param object 
  32. */ 
  33. public static void writeJson(HttpServletResponse response, Object object) { 
  34. writeJson(response, HttpServletResponse.SC_OK, object); 
  35.  
  36. /** 
  37. * 返回json數(shù)據(jù) 
  38. * @param response 
  39. * @param object 
  40. */ 
  41. public static void writeJson(ServletResponse response, Object object) { 
  42. if (response instanceof HttpServletResponse) { 
  43. writeJson((HttpServletResponse) response, object); 
  44. 復(fù)制代碼 

工具類中使用了Gson,需要引用:

  
  
  
  
  1.  
  2. com.google.code.gson 
  3. gson 
  4.  
  5. 復(fù)制代碼 

@ControllerAdvice + @ExceptionHandler

該方式與第一種方式類似,如下:

  
  
  
  
  1. @Slf4j 
  2. @ControllerAdvice 
  3. public class GlobalExceptionHandler { 
  4.  
  5. /** 
  6. * BusinessException 異常處理 
  7. */ 
  8. @ResponseBody 
  9. @ExceptionHandler(BusinessException.class) 
  10. public ApiResult businessExceptionHandler(BusinessException e) { 
  11. log.error(e.getMessage(), e); 
  12. // do something 
  13. return ApiResult.fail(e.getMessage()); 
  14.  
  15. /** 
  16. * Exception 異常處理 
  17. */ 
  18. @ResponseBody 
  19. @ExceptionHandler(Exception.class) 
  20. public ApiResult exceptionHandler(Exception e) { 
  21. log.error(e.getMessage(), e); 
  22. return ApiResult.fail("服務(wù)異常,請稍后重試"); 
  23. 復(fù)制代碼 

總結(jié)

三種方式都能很好對異常進(jìn)行統(tǒng)一處理,但是一般推薦使用@ControllerAdvice + @ExceptionHandler方式, 這樣能夠使異常處理與業(yè)務(wù)邏輯分離,并且不用自己處理Json數(shù)據(jù)返回。

源碼

github.com/zhuqianchan…


網(wǎng)頁名稱:從零搭建后端框架——異常統(tǒng)一處理的三種方式
標(biāo)題來源:http://www.dlmjj.cn/article/cdjehoc.html