從零搭建本身的SpringBoot後臺框架(五)

Hello你們好,本章咱們添加全局異常處理。有問題能夠聯繫我mr_beany@163.com。另求各路大神指點,感謝

一:爲何須要定義全局異常

在互聯網時代,咱們所開發的應用大可能是直面用戶的,程序中的任何一點小疏忽均可能致使用戶的流失,而程序出現異常每每又是不可避免的,因此咱們須要對異常進行捕獲,而後給予相應的處理,來減小程序異常對用戶體驗的影響
java

二:添加業務類異常

在前面說過的ret文件夾下建立ServiceExceptiongit

package com.example.demo.core.ret;

import java.io.Serializable;

/**
 * @Description: 業務類異常
 * @author 張瑤
 * @date 2018/4/20 14:30
 * 
 */
public class ServiceException extends RuntimeException implements Serializable{

   private static final long serialVersionUID = 1213855733833039552L;

   public ServiceException() {
   }

   public ServiceException(String message) {
      super(message);
   }

   public ServiceException(String message, Throwable cause) {
      super(message, cause);
   }
}複製代碼

三:添加異常處理配置

打開上篇文章建立的WebConfigurer,添加以下方法github

@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
    exceptionResolvers.add(getHandlerExceptionResolver());
}

/**
 * 建立異常處理
 * @return
 */
private HandlerExceptionResolver getHandlerExceptionResolver(){
    HandlerExceptionResolver handlerExceptionResolver = new HandlerExceptionResolver(){
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
                                             Object handler, Exception e) {
            RetResult<Object> result = getResuleByHeandleException(request, handler, e);
            responseResult(response, result);
            return new ModelAndView();
        }
    };
    return handlerExceptionResolver;
}

/**
 * 根據異常類型肯定返回數據
 * @param request
 * @param handler
 * @param e
 * @return
 */
private RetResult<Object> getResuleByHeandleException(HttpServletRequest request, Object handler, Exception e){
    RetResult<Object> result = new RetResult<>();
    if (e instanceof ServiceException) {
        result.setCode(RetCode.FAIL).setMsg(e.getMessage()).setData(null);
        return result;
    }
    if (e instanceof NoHandlerFoundException) {
        result.setCode(RetCode.NOT_FOUND).setMsg("接口 [" + request.getRequestURI() + "] 不存在");
        return result;
    }
    result.setCode(RetCode.INTERNAL_SERVER_ERROR).setMsg("接口 [" + request.getRequestURI() + "] 內部錯誤,請聯繫管理員");
    String message;
    if (handler instanceof HandlerMethod) {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        message = String.format("接口 [%s] 出現異常,方法:%s.%s,異常摘要:%s", request.getRequestURI(),
                handlerMethod.getBean().getClass().getName(), handlerMethod.getMethod() .getName(), e.getMessage());
    } else {
        message = e.getMessage();
    }
    LOGGER.error(message, e);
    return result;
}

/**
 * @Title: responseResult
 * @Description: 響應結果
 * @param response
 * @param result
 * @Reutrn void
 */
private void responseResult(HttpServletResponse response, RetResult<Object> result) {
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Content-type", "application/json;charset=UTF-8");
    response.setStatus(200);
    try {
        response.getWriter().write(JSON.toJSONString(result,SerializerFeature.WriteMapNullValue));
    } catch (IOException ex) {
        LOGGER.error(ex.getMessage());
    }
}複製代碼

四:添加配置文件

Spring Boot 中, 當用戶訪問了一個不存在的連接時, Spring 默認會將頁面重定向到 **/error** 上, 而不會拋出異常. web

既然如此, 那咱們就告訴 Spring Boot, 當出現 404 錯誤時, 拋出一個異常便可. spring

application.properties 中添加兩個配置: json

spring.mvc.throw-exception-if-no-handler-found=true springboot

spring.resources.add-mappings=false bash

上面的配置中, 第一個 spring.mvc.throw-exception-if-no-handler-found 告訴 SpringBoot 當出現 404 錯誤時, 直接拋出異常. 第二個 spring.resources.add-mappings 告訴 SpringBoot 不要爲咱們工程中的資源文件創建映射.
mvc

五:建立測試接口

package com.example.demo.service.impl;

import com.example.demo.core.ret.ServiceException;
import com.example.demo.dao.UserInfoMapper;
import com.example.demo.model.UserInfo;
import com.example.demo.service.UserInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 張瑤
 * @Description:
 * @time 2018/4/18 11:56
 */
@Service
public class UserInfoServiceImpl implements UserInfoService{

    @Resource
    private UserInfoMapper userInfoMapper;

    @Override
    public UserInfo selectById(Integer id){
        UserInfo userInfo = userInfoMapper.selectById(id);
        if(userInfo == null){
            throw new ServiceException("暫無該用戶");
        }
        return userInfo;
    }
}複製代碼

UserInfoController.javaapp

package com.example.demo.controller;

import com.example.demo.core.ret.RetResponse;
import com.example.demo.core.ret.RetResult;
import com.example.demo.core.ret.ServiceException;
import com.example.demo.model.UserInfo;
import com.example.demo.service.UserInfoService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 張瑤
 * @Description:
 * @time 2018/4/18 11:39
 */
@RestController
@RequestMapping("userInfo")
public class UserInfoController {

    @Resource
    private UserInfoService userInfoService;

    @PostMapping("/hello")
    public String hello(){
        return "hello SpringBoot";
    }

    @PostMapping("/selectById")
    public RetResult<UserInfo> selectById(Integer id){
        UserInfo userInfo = userInfoService.selectById(id);
        return RetResponse.makeOKRsp(userInfo);
    }

    @PostMapping("/testException")
    public RetResult<UserInfo> testException(Integer id){
        List a = null;
        a.size();
        UserInfo userInfo = userInfoService.selectById(id);
        return RetResponse.makeOKRsp(userInfo);
    }


}複製代碼

六:接口測試

訪問192.168.1.104:8080/userInfo/selectById參數 id:3

{
    "code": 400,
    "data": null,
    "msg": "暫無該用戶"
}複製代碼

訪問192.168.1.104:8080/userInfo/testException

{
    "code": 500,
    "data": null,
    "msg": "接口 [/userInfo/testException] 內部錯誤,請聯繫管理員"
}複製代碼

項目地址

碼雲地址: gitee.com/beany/mySpr…

GitHub地址: github.com/MyBeany/myS…

寫文章不易,如對您有幫助,請幫忙點下star

結尾

springboot添加全局異常處理已完成,後續功能接下來陸續更新,有問題能夠聯繫我mr_beany@163.com。另求各路大神指點,感謝你們。

相關文章
相關標籤/搜索