Spring框架增強-全域性異常處理機制-根據目錄結構自動生成路由字首-引數效驗機制以及自定義效驗

程式猿與汪發表於2020-12-23

全域性異常處理機制

我們應該做一個統一錯誤響應,返回給前端的應該是意義明確的json結構

{
    code:10001
    message:xxxx
    request:GET url
}

message:是錯誤響應的具體訊息

code:代表的是錯誤型別編碼

request:表示當前介面訪問的url

1.GlobalExceptionAdvice

//接收專案丟擲的異常
@ControllerAdvice //特定註解實現加入spring容器
public class GlibalExceptionAdvice{
    
    //注入配置類,供下文中程式碼獲取到其中的message資訊
    @Autowired
    private ExceptionCodeConfiguration codeCongiguration; 
    
    @ExceptionHandler(value=Exception.class)//通過指定value處理通用的異常(未知異常)
    @ResponseBody //打上這個註解,資料才可以返回到前端
    @ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR) //設定指定當前返回的錯誤狀態碼:500
    //HttpServletRequest這個物件獲取當前訪問介面的url
    public UnifyResponse hadleException(HttpServletRequest req,Exception e){ 
        String requestUrl = req.getRequestURI();
        String method = req.getMethod();
        System.out.println(e); //列印一下異常,方便進行後端開發時除錯
        UnifyResponse message = new UnifyResponse(999,'伺服器異常',method +' '+ requestUrl);
        return message;
} 
    @ExceptionHandler(value=HttpException.class) //只監聽http異常(已知異常)
    public RespomseEntity hadlehttpException(HttpServletRequest req,HttpException e){ 
        String requestUrl = req.getRequestURI();
        String method = req.getMethod();
    	/*
    	*HttpHeaders是Spring自帶的起到的作用是可以設定返回的型別
    	*以前為什麼我們沒有設定,現在設定了那?
    	*因為我們使用了@ResponseBody註解,他自動幫我們進行了設定,現在沒有使用我們需要自己進行設定
    	*/
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON); //因為我們是API,所以要將型別設定為JSON
        
        UnifyResponse message = new UnifyResponse(e.getCode(),codeConfiguration.getMessage(e.getCode),method +' '+ requestUrl);
        /*
    	*HttpStatus是Spring自帶的起到的作用是可以靈活的根據HttpException異常類獲取狀態碼
    	*以前為什麼我們沒有設定,現在設定了那?
    	*因為我們使用了@ResponseBody註解,他自動幫我們進行了設定,現在沒有使用我們需要自己進行設定
    	*/
        HttpStatus httpstatus = HttpStatus.resolve(e.getHttpStatusCode());
        //RespomseEntity可以在裡面設定很多屬性,這種粒度的控制比上面直接return一個物件會更加
        //RespomseEntity返回成什麼樣的型別就將其指定為什麼型別泛型
        RespomseEntity<UnifyResponse> r = new RespomseEntity<>(message,headers,httpstatus)
        return r;     
	} 
}

2.HttpException

import lombdo
//HttpException代表了一類和http相關的異常
@get
public class HttpException extends RuntimeException{
    protected Integer code;
    //http狀態碼
    protected Integer httpStatusCode=500;
}

3.NotFoundException

public class NotFoundException extends HttpException{
    public NotFoundException(int code){
        this.httpStatusCode=404; //覆蓋父類的狀態碼
        this.code=code; //接收使用者傳入的code
    }
}

4.ForbiddenException

public class ForbiddenException extends HttpException{
    public ForbiddenException(int code){
        this.code = code;
        this.httpStatusCode = 403; //許可權不足
    }
}

5.UnifyResponse

//統一錯誤響應格式 
import lombad
@get
public calss UnifyResponse{
    private int code;
    private String message;
    private String request;
    
    public UbifyRequest(int code,String message,String request){
        this.code = code;
        this.message = mesage;
        this.request = request;
    }
} 

6.exception-code.properties

//動態將異常資訊message從配置中獲取傳入程式碼中,避免硬編碼寫message
lin.codes[10001] = 通用引數錯誤 //配置檔案不要加單引號,雙引號,spring會自動新增的
lin.codes[10000] = 通用異常

7.ExceptionCodeConfiguration

/*因為我們的需求是動態的載入配置中的異常狀態碼資訊,
*我們沒法使用@Value這種硬編碼的方式,為了實現動態獲取,
*我們需要維護一個配置檔案的配置類
*/
//如何將一個類和配置檔案進行對應,spring已經實現好了,新增@PropertySource註解即可實現配置檔案和配置類進行對應
@PropertySource(value = "classpath:config/excepetion-code.properties") // classpath:類路徑下
/*
*怎麼使配置檔案中的配置項和配置類中欄位進行一一對應,spring已經實現好了,
*通過@ConfigurationProperties註解的prefix定義配置項的字首,就可實現配
*置項和欄位對應
*/
@ConfigurationProperties(prefix = "lin") 
@Component//注入容器,才能受springBoot的同一管理
public class EceptionCodeonfiguration{
    private Map<Integer,String> codes = new HashMap<>();
    public String getMessage(int code){
        String message = codes.get(code);
        return message;	
    }
}

根據目錄結構自動生成路由字首

1.BannerController

    //api介面
    @RestController
    @RequestMapping("/banner")
    public class BannerController{
        @Autowired
        private ISkill iSkill;
        
        @GetMapping("/tets")
        public String test(){
            iSkill.r()
        }
    }

2.AutoPrefixUrlMapping

//RequsetMappingHandlerMapping類就是spring定義的處理帶有RequsetMapping註解的collection的
public class AutoPrefixUrlMapping extends RequsetMappingHandlerMapping{
    @Override
    protected RequestMappingInfo getMappingForMethod(Method method,Class<?> handlerTyoe){        //接收一下
        RequestMappingInfo mappingInfo = super.getMappingForMethod(method,handlerType);
    if(mappingInfo != null){//不為空我們就進行路由資訊的修改
        
    	}
        return 
	}
    private String getPrefix(Class<?> handlerTyoe){
        String packageName = hadleType.getPackage().getName();
        return packageName
    }
}

3.AutoPrefixConfiguration

   //配置類:將AutoPrefixUrlMapping注入到spring容器中
    @Component
    public class AutoPrefixConfiguration implements WebMvcRegistrations{
        @Override
        public RequestMappingHandleMapping getRequestMapping{
            return new AutoPrefixUrlMapping
        }
    }

引數效驗機制以及自定義效驗

相關文章