0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

SpringBoot攔截器與統(tǒng)一功能處理實(shí)戰(zhàn)

jf_ro2CN3Fa ? 來源:CSDN ? 2023-08-27 10:44 ? 次閱讀

前言

Spring AOP是一個基于面向切面編程的框架,用于將橫切性關(guān)注點(diǎn)(如日志記錄、事務(wù)管理)與業(yè)務(wù)邏輯分離,通過代理對象將這些關(guān)注點(diǎn)織入到目標(biāo)對象的方法執(zhí)行前后、拋出異?;蚍祷亟Y(jié)果時等特定位置執(zhí)行,從而提高程序的可復(fù)用性、可維護(hù)性和靈活性。

但使用原生Spring AOP實(shí)現(xiàn)統(tǒng)一的攔截是非常繁瑣、困難的。而在本節(jié),我們將使用一種簡單的方式進(jìn)行統(tǒng)一功能處理,這也是AOP的一次實(shí)戰(zhàn),具體如下:

統(tǒng)一用戶登錄權(quán)限驗(yàn)證

統(tǒng)一數(shù)據(jù)格式返回

統(tǒng)一異常處理

0 為什么需要統(tǒng)一功能處理?

統(tǒng)一功能處理是為了提高代碼的可維護(hù)性、可重用性和可擴(kuò)展性而進(jìn)行的一種設(shè)計(jì)思想。在應(yīng)用程序中,可能存在一些通用的功能需求,例如身份驗(yàn)證、日志記錄、異常處理等。

這些功能需要在多個地方進(jìn)行調(diào)用和處理,如果每個地方都單獨(dú)實(shí)現(xiàn)這些功能,會導(dǎo)致代碼冗余、難以維護(hù)和重復(fù)勞動。通過統(tǒng)一功能處理的方式,可以將這些通用功能抽取出來,以統(tǒng)一的方式進(jìn)行處理。這樣做有以下幾個好處:

「代碼復(fù)用」 :將通用功能抽取成獨(dú)立的模塊或組件,可以在多個地方共享使用,減少重復(fù)編寫代碼的工作量。

「可維護(hù)性」 :將通用功能集中處理,可以方便地對其進(jìn)行修改、優(yōu)化或擴(kuò)展,而不需要在多個地方進(jìn)行修改。

「代碼整潔性」 :通過統(tǒng)一功能處理,可以使代碼更加清晰、簡潔,減少了冗余的代碼。

「可擴(kuò)展性」 :當(dāng)需要添加新的功能時,只需要在統(tǒng)一功能處理的地方進(jìn)行修改或擴(kuò)展,而不需要在多個地方進(jìn)行修改,降低了代碼的耦合度。

1 統(tǒng)一用戶登錄權(quán)限驗(yàn)證

1.1 使用原生 Spring AOP 實(shí)現(xiàn)統(tǒng)一攔截的難點(diǎn)

以使用原生 Spring AOP 來實(shí)現(xiàn)?戶統(tǒng)?登錄驗(yàn)證為例,主要是使用前置通知和環(huán)繞通知實(shí)現(xiàn)的,具體實(shí)現(xiàn)如下

importorg.aspectj.lang.ProceedingJoinPoint;
importorg.aspectj.lang.annotation.*;
importorg.springframework.stereotype.Component;

/**
*@author興趣使然黃小黃
*@version1.0
*@date2023/7/1816:37
*/
@Aspect//表明此類為一個切面
@Component//隨著框架的啟動而啟動
publicclassUserAspect{
//定義切點(diǎn),這里使用Aspect表達(dá)式語法
@Pointcut("execution(*com.hxh.demo.controller.UserController.*(..))")
publicvoidpointcut(){}


//前置通知
@Before("pointcut()")
publicvoidbeforeAdvice(){
System.out.println("執(zhí)行了前置通知~");
}

//環(huán)繞通知
@Around("pointcut()")
publicObjectaroundAdvice(ProceedingJoinPointjoinPoint){
System.out.println("進(jìn)入環(huán)繞通知~");
Objectobj=null;
//執(zhí)行目標(biāo)方法
try{
obj=joinPoint.proceed();
}catch(Throwablee){
e.printStackTrace();
}
System.out.println("退出環(huán)繞通知~");
returnobj;
}

}

從上述的代碼示例可以看出,使用原生的 Spring AOP 實(shí)現(xiàn)統(tǒng)一攔截的難點(diǎn)主要有以下幾個方面:

定義攔截規(guī)則非常困難。如注冊?法和登錄?法是不攔截的,這樣的話排除?法的規(guī)則很難定義,甚?沒辦法定義。

在切面類中拿到 HttpSession 比較難。

為了解決 Spring AOP 的這些問題,Spring 提供了攔截器~

1.2 使用 Spring 攔截器實(shí)現(xiàn)統(tǒng)一用戶登錄驗(yàn)證

Spring攔截器是Spring框架提供的一個功能強(qiáng)大的組件,用于在請求到達(dá)控制器之前或之后進(jìn)行攔截和處理。攔截器可以用于實(shí)現(xiàn)各種功能,如身份驗(yàn)證、日志記錄、性能監(jiān)測等。

要使用Spring攔截器,需要創(chuàng)建一個實(shí)現(xiàn)了HandlerInterceptor接口的攔截器類。該接口定義了三個方法:preHandle、postHandle和afterCompletion。

preHandle方法在請求到達(dá)控制器之前執(zhí)行,可以用于進(jìn)行身份驗(yàn)證、參數(shù)校驗(yàn)等;

postHandle方法在控制器處理完請求后執(zhí)行,可以對模型和視圖進(jìn)行操作;

afterCompletion方法在視圖渲染完成后執(zhí)行,用于清理資源或記錄日志。

攔截器的實(shí)現(xiàn)可以分為以下兩個步驟:

創(chuàng)建自定義攔截器,實(shí)現(xiàn) HandlerInterceptor 接口的 preHandle(執(zhí)行具體方法之前的預(yù)處理)方法。

將自定義攔截器加入 WebMvcConfigurer 的 addInterceptors 方法中,并且設(shè)置攔截規(guī)則。

具體實(shí)現(xiàn)如下:

step1. 創(chuàng)建自定義攔截器,自定義攔截器是一個普通類,代碼如下:

importorg.springframework.web.servlet.HandlerInterceptor;

importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjavax.servlet.http.HttpSession;

/**
*@author興趣使然黃小黃
*@version1.0
*@date2023/7/1916:31
*統(tǒng)一用戶登錄權(quán)限驗(yàn)證——登錄攔截器
*/
publicclassLoginInterceptorimplementsHandlerInterceptor{
@Override
publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{
//用戶登錄業(yè)務(wù)判斷
HttpSessionsession=request.getSession(false);
if(session!=null&&session.getAttribute("userinfo")!=null){
returntrue;//驗(yàn)證成功,繼續(xù)controller的流程
}
//可以跳轉(zhuǎn)登錄界面或者返回401/403沒有權(quán)限碼
response.sendRedirect("/login.html");//跳轉(zhuǎn)到登錄頁面
returnfalse;//驗(yàn)證失敗
}
}

step2. 配置攔截器并設(shè)置攔截規(guī)則,代碼如下:

importorg.springframework.context.annotation.Configuration;
importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
*@author興趣使然黃小黃
*@version1.0
*@date2023/7/1916:51
*/
@Configuration
publicclassAppConfigimplementsWebMvcConfigurer{
@Override
publicvoidaddInterceptors(InterceptorRegistryregistry){
registry.addInterceptor(newLoginInterceptor())
.addPathPatterns("/**")//攔截所有請求
.excludePathPatterns("/user/login")//不攔截的url地址
.excludePathPatterns("/user/reg")
.excludePathPatterns("/**/*.html");//不攔截所有頁面
}
}

1.3 攔截器的實(shí)現(xiàn)原理及源碼分析

當(dāng)有了攔截器后,會在調(diào)用 Controller 之前進(jìn)行相應(yīng)的業(yè)務(wù)處理,執(zhí)行的流程如下圖所示:

8932c162-4482-11ee-a2ef-92fbcf53809c.png

「攔截器實(shí)現(xiàn)原理的源碼分析」

從上述案例實(shí)現(xiàn)結(jié)果的控制臺的日志信息可以看出,所有的 Controller 執(zhí)?都會通過?個調(diào)度器 DispatcherServlet 來實(shí)現(xiàn)。

8990fae8-4482-11ee-a2ef-92fbcf53809c.png

而所有的方法都會執(zhí)行 DispatcherServlet 中的 doDispatch 調(diào)度方法,doDispatch 源碼如下:

protectedvoiddoDispatch(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{
HttpServletRequestprocessedRequest=request;
HandlerExecutionChainmappedHandler=null;
booleanmultipartRequestParsed=false;
WebAsyncManagerasyncManager=WebAsyncUtils.getAsyncManager(request);
try{
try{
ModelAndViewmv=null;
ObjectdispatchException=null;
try{
processedRequest=this.checkMultipart(request);
multipartRequestParsed=processedRequest!=request;
mappedHandler=this.getHandler(processedRequest);
if(mappedHandler==null){
this.noHandlerFound(processedRequest,response);
return;
}
HandlerAdapterha=this.getHandlerAdapter(mappedHandler.getHandler());
Stringmethod=request.getMethod();
booleanisGet=HttpMethod.GET.matches(method);
if(isGet||HttpMethod.HEAD.matches(method)){
longlastModified=ha.getLastModified(request,mappedHandler.getHandler());
if((newServletWebRequest(request,response)).checkNotModified(lastModified)&&isGet){
return;
}
}

//調(diào)用預(yù)處理
if(!mappedHandler.applyPreHandle(processedRequest,response)){
return;
}
//執(zhí)行Controller中的業(yè)務(wù)
mv=ha.handle(processedRequest,response,mappedHandler.getHandler());
if(asyncManager.isConcurrentHandlingStarted()){
return;
}
this.applyDefaultViewName(processedRequest,mv);
mappedHandler.applyPostHandle(processedRequest,response,mv);
}catch(Exceptionvar20){
dispatchException=var20;
}catch(Throwablevar21){
dispatchException=newNestedServletException("Handlerdispatchfailed",var21);
}
this.processDispatchResult(processedRequest,response,mappedHandler,mv,(Exception)dispatchException);
}catch(Exceptionvar22){
this.triggerAfterCompletion(processedRequest,response,mappedHandler,var22);
}catch(Throwablevar23){
this.triggerAfterCompletion(processedRequest,response,mappedHandler,newNestedServletException("Handlerprocessingfailed",var23));
}
}finally{
if(asyncManager.isConcurrentHandlingStarted()){
if(mappedHandler!=null){
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest,response);
}
}elseif(multipartRequestParsed){
this.cleanupMultipart(processedRequest);
}
}
}

從上述源碼可以看出,在執(zhí)行 Controller 之前,先會調(diào)用 預(yù)處理方法 applyPreHandle,該方法源碼如下:

booleanapplyPreHandle(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{
for(inti=0;i

在上述源碼中,可以看出,在 applyPreHandle 中會獲取所有攔截器 HandlerInterceptor 并執(zhí)行攔截器中的 preHandle 方法,這與之前我們實(shí)現(xiàn)攔截器的步驟對應(yīng),如下圖所示:

89dc818e-4482-11ee-a2ef-92fbcf53809c.png

此時,相應(yīng)的preHandle中的業(yè)務(wù)邏輯就會執(zhí)行。

1.4 統(tǒng)一訪問前綴添加

統(tǒng)一訪問前綴的添加與登錄攔截器實(shí)現(xiàn)類似,即給所有請求地址添加 /hxh 前綴,示例代碼如下:

@Configuration
publicclassAppConfigimplementsWebMvcConfigurer{
//給所有接口添加/hxh前綴
@Override
publicvoidconfigurePathMatch(PathMatchConfigurerconfigurer){
configurer.addPathPrefix("/hxh",c->true);
}
}

另一種方式是在application配置文件中配置:

server.servlet.context-path=/hxh

2 統(tǒng)一異常處理

統(tǒng)一異常處理是指 在應(yīng)用程序中定義一個公共的異常處理機(jī)制,用來處理所有的異常情況。 這樣可以避免在應(yīng)用程序中分散地處理異常,降低代碼的復(fù)雜度和重復(fù)度,提高代碼的可維護(hù)性和可擴(kuò)展性。

需要考慮以下幾點(diǎn):

異常處理的層次結(jié)構(gòu):定義異常處理的層次結(jié)構(gòu),確定哪些異常需要統(tǒng)一處理,哪些異常需要交給上層處理。

異常處理的方式:確定如何處理異常,比如打印日志、返回錯誤碼等。

異常處理的細(xì)節(jié):處理異常時需要注意的一些細(xì)節(jié),比如是否需要事務(wù)回滾、是否需要釋放資源等

本文講述的統(tǒng)一異常處理使用的是 @ControllerAdvice + @ExceptionHandler 來實(shí)現(xiàn)的:

@ControllerAdvice 表示控制器通知類。

@ExceptionHandler 異常處理器。

以上兩個注解組合使用,表示當(dāng)出現(xiàn)異常的時候執(zhí)行某個通知,即執(zhí)行某個方法事件,具體實(shí)現(xiàn)代碼如下:

importorg.springframework.web.bind.annotation.ControllerAdvice;
importorg.springframework.web.bind.annotation.ExceptionHandler;
importorg.springframework.web.bind.annotation.ResponseBody;

importjava.util.HashMap;

/**
*@author興趣使然黃小黃
*@version1.0
*@date2023/7/1918:27
*統(tǒng)一異常處理
*/
@ControllerAdvice//聲明是一個異常處理器
publicclassMyExHandler{

//攔截所有的空指針異常,進(jìn)行統(tǒng)一的數(shù)據(jù)返回
@ExceptionHandler(NullPointerException.class)//統(tǒng)一處理空指針異常
@ResponseBody//返回?cái)?shù)據(jù)
publicHashMapnullException(NullPointerExceptione){
HashMapresult=newHashMap<>();
result.put("code","-1");//與前端定義好的異常狀態(tài)碼
result.put("msg","空指針異常:"+e.getMessage());//錯誤碼的描述信息
result.put("data",null);//返回的數(shù)據(jù)
returnresult;
}
}

上述代碼中,實(shí)現(xiàn)了對所有空指針異常的攔截并進(jìn)行統(tǒng)一的數(shù)據(jù)返回。

在實(shí)際中,常常設(shè)置一個保底,比如發(fā)生的非空指針異常,也會有保底措施進(jìn)行處理,類似于 try-catch 塊中使用 Exception 進(jìn)行捕獲,代碼示例如下:

@ExceptionHandler(Exception.class)
@ResponseBody
publicHashMapexception(Exceptione){
HashMapresult=newHashMap<>();
result.put("code","-1");//與前端定義好的異常狀態(tài)碼
result.put("msg","異常:"+e.getMessage());//錯誤碼的描述信息
result.put("data",null);//返回的數(shù)據(jù)
returnresult;
}

3 統(tǒng)一數(shù)據(jù)返回格式

為了保持 API 的一致性和易用性,通常需要使用統(tǒng)一的數(shù)據(jù)返回格式。 一般而言,一個標(biāo)準(zhǔn)的數(shù)據(jù)返回格式應(yīng)該包括以下幾個元素:

狀態(tài)碼:用于標(biāo)志請求成功失敗的狀態(tài)信息;

消息:用來描述請求狀態(tài)的具體信息;

數(shù)據(jù):包含請求的數(shù)據(jù)信息;

時間戳:可以記錄請求的時間信息,便于調(diào)試和監(jiān)控。

實(shí)現(xiàn)統(tǒng)一的數(shù)據(jù)返回格式可以使用 @ControllerAdvice + ResponseBodyAdvice 的方式實(shí)現(xiàn),具體步驟如下:

創(chuàng)建一個類,并添加 @ControllerAdvice 注解;

實(shí)現(xiàn) ResponseBodyAdvice 接口,并重寫 supports 和 beforeBodyWrite 方法。

示例代碼如下:

importorg.springframework.core.MethodParameter;
importorg.springframework.http.MediaType;
importorg.springframework.http.server.ServerHttpRequest;
importorg.springframework.http.server.ServerHttpResponse;
importorg.springframework.web.bind.annotation.ControllerAdvice;
importorg.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

importjava.util.HashMap;

/**
*@author興趣使然黃小黃
*@version1.0
*@date2023/7/1918:59
*統(tǒng)一數(shù)據(jù)返回格式
*/
@ControllerAdvice
publicclassResponseAdviceimplementsResponseBodyAdvice{

/**
*此方法返回true則執(zhí)行下面的beforeBodyWrite方法,反之則不執(zhí)行
*/
@Override
publicbooleansupports(MethodParameterreturnType,ClassconverterType){
returntrue;
}

/**
*方法返回之前調(diào)用此方法
*/
@Override
publicObjectbeforeBodyWrite(Objectbody,MethodParameterreturnType,MediaTypeselectedContentType,ClassselectedConverterType,ServerHttpRequestrequest,ServerHttpResponseresponse){
HashMapresult=newHashMap<>();
result.put("code",200);
result.put("msg","");
result.put("data",body);
returnnull;
}
}

但是,如果返回的 body 原始數(shù)據(jù)類型是 String ,則會出現(xiàn)類型轉(zhuǎn)化異常,即 ClassCastException。

因此,如果原始返回?cái)?shù)據(jù)類型為 String ,則需要使用 jackson 進(jìn)行單獨(dú)處理,實(shí)現(xiàn)代碼如下:

importcom.fasterxml.jackson.core.JsonProcessingException;
importcom.fasterxml.jackson.databind.ObjectMapper;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.core.MethodParameter;
importorg.springframework.http.MediaType;
importorg.springframework.http.server.ServerHttpRequest;
importorg.springframework.http.server.ServerHttpResponse;
importorg.springframework.web.bind.annotation.ControllerAdvice;
importorg.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

importjava.util.HashMap;

/**
*@author興趣使然黃小黃
*@version1.0
*@date2023/7/1918:59
*統(tǒng)一數(shù)據(jù)返回格式
*/
@ControllerAdvice
publicclassResponseAdviceimplementsResponseBodyAdvice{

@Autowired
privateObjectMapperobjectMapper;

/**
*此方法返回true則執(zhí)行下面的beforeBodyWrite方法,反之則不執(zhí)行
*/
@Override
publicbooleansupports(MethodParameterreturnType,ClassconverterType){
returntrue;
}

/**
*方法返回之前調(diào)用此方法
*/
@Override
publicObjectbeforeBodyWrite(Objectbody,MethodParameterreturnType,MediaTypeselectedContentType,ClassselectedConverterType,ServerHttpRequestrequest,ServerHttpResponseresponse){
HashMapresult=newHashMap<>();
result.put("code",200);
result.put("msg","");
result.put("data",body);
if(bodyinstanceofString){
//需要對String特殊處理
try{
returnobjectMapper.writeValueAsString(result);
}catch(JsonProcessingExceptione){
e.printStackTrace();
}
}
returnresult;
}
}

但是,在實(shí)際業(yè)務(wù)中,上述代碼只是作為保底使用,因?yàn)闋顟B(tài)碼始終返回的是200,過于死板,還需要具體問題具體分析。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19118

    瀏覽量

    228864
  • 控制器
    +關(guān)注

    關(guān)注

    112

    文章

    16133

    瀏覽量

    177138
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    491

    瀏覽量

    27461
  • SpringBoot
    +關(guān)注

    關(guān)注

    0

    文章

    173

    瀏覽量

    161

原文標(biāo)題:告別繁瑣:SpringBoot 攔截器與統(tǒng)一功能處理

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    HarmonyOS實(shí)戰(zhàn)開發(fā)-如何在Navigation中完成路由攔截

    路由攔截器interceptor.ets,定義攔截容器、注冊方法和公共攔截邏輯,interceptor.ets /** * 定義攔截實(shí)現(xiàn)接口 * * @param routerI
    發(fā)表于 05-08 14:21

    [推薦]奧運(yùn)全球眼 網(wǎng)絡(luò)視頻攝像機(jī) 電話報(bào)警系統(tǒng) -電話報(bào)警 GSM防盜

    ........................................................ 10012.4.1 個生命周期回調(diào)事件上有多個回調(diào)攔截器方法...... 10112.4.2 異常
    發(fā)表于 07-07 15:39

    我想做個號碼攔截器。面對面5米內(nèi)接收到對方的手機(jī)號碼。我也咨詢很多人,不是技

    我想做個號碼攔截器。面對面5米內(nèi)接收到對方的手機(jī)號碼。我也咨詢很多人,不是技術(shù)問題就是,怕這東西觸犯法律。我只是正規(guī)用途,并不會觸犯法律底線!望“能人”解決我的問題!樣品只要符合以上條件,重金酬謝...謝謝!QQ896776242加我請注明電子*** 丁先生
    發(fā)表于 04-29 16:16

    Springboot是如何獲取自定義異常并進(jìn)行返回的

    HandlerExceptionResolver這里呢?看下代碼:走完初始化,經(jīng)過過濾器,攔截器終于到了我們的請求方法,我們的方法還報(bào)錯了,所以會走到異常中,我們DispatcherServlet會
    發(fā)表于 03-22 14:15

    網(wǎng)絡(luò)組件axios可以在OpenHarmony上使用了

    攔截器也是如此功能,只是在請求得到響應(yīng)之后,對響應(yīng)體的處理,通常是數(shù)據(jù)統(tǒng)一處理等,也常來判斷登錄失效等。axios的
    發(fā)表于 08-29 12:11

    動能攔截器六自由度仿真建模研究

    仿真建模技術(shù)是動能攔截器制導(dǎo)律研究中的重要技術(shù),文中主要建立動能攔截器的軌道運(yùn)動動力學(xué)以及姿態(tài)運(yùn)動動力學(xué)模型,并建立完整的制導(dǎo)控制系統(tǒng)數(shù)學(xué)模型。文末,以某型
    發(fā)表于 08-07 08:50 ?14次下載

    springmvc 自定義攔截器實(shí)現(xiàn)未登錄用戶的攔截

    springmvc自定義攔截器實(shí)現(xiàn)未登錄用戶的攔截
    發(fā)表于 11-25 14:44 ?2508次閱讀
    springmvc 自定義<b class='flag-5'>攔截器</b>實(shí)現(xiàn)未登錄用戶的<b class='flag-5'>攔截</b>

    Spring Boot 系列(八)@ControllerAdvice 攔截異常并統(tǒng)一處理

    Spring Boot 系列(八)@ControllerAdvice 攔截異常并統(tǒng)一處理 在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定義
    發(fā)表于 01-16 18:39 ?293次閱讀

    快速定位SpringBoot接口超時問題的神器

    渠道系統(tǒng)是個常見的spring-boot web工程,使用了集成的tomcat。分析了代碼之后,發(fā)現(xiàn)并沒有特殊的地方,沒有特殊的過濾器或者攔截器,所以初步排除是業(yè)務(wù)代碼問題
    的頭像 發(fā)表于 10-19 10:22 ?765次閱讀

    公司這套架構(gòu)統(tǒng)一處理try...catch真香!

    有大量的冗余代碼,而且還影響代碼的可讀性。這樣就需要定義個全局統(tǒng)一異常處理器,以便業(yè)務(wù)層再也不必處理異常。
    的頭像 發(fā)表于 02-27 10:47 ?454次閱讀

    核心功能具體的執(zhí)行過程-2

    這篇我們主要講解下 axios 中的 配置、攔截器和執(zhí)行鏈等些核心的功能到底是怎么運(yùn)行的。
    的頭像 發(fā)表于 03-01 09:59 ?533次閱讀
    核心<b class='flag-5'>功能</b>具體的執(zhí)行過程-2

    什么是 SpringBoot?

    本文從為什么要有 `SpringBoot`,以及 `SpringBoot` 到底方便在哪里開始入手,逐步分析了 `SpringBoot` 自動裝配的原理,最后手寫了個簡單的 `sta
    的頭像 發(fā)表于 04-07 11:28 ?1258次閱讀
    什么是 <b class='flag-5'>SpringBoot</b>?

    SpringBoot統(tǒng)一功能處理

    最初用戶登錄效驗(yàn): 在每個方法中獲取 Session 和 Session 中的用戶信息,如果存在用戶,那么就認(rèn)為登錄成功了,否則就登錄失敗了
    的頭像 發(fā)表于 04-19 14:51 ?615次閱讀

    springboot過濾器和攔截器哪個先執(zhí)行

    Spring Boot是個用于構(gòu)建Java應(yīng)用程序的開發(fā)框架,它提供了許多功能和工具來簡化開發(fā)和部署過程。其中兩個重要的功能是過濾器和攔截器。本文將詳細(xì)介紹Spring Boot過濾
    的頭像 發(fā)表于 12-03 15:00 ?2381次閱讀

    使用go語言實(shí)現(xiàn)個grpc攔截器

    在開發(fā)grpc服務(wù)時,我們經(jīng)常會遇到些通用的需求,比如:日志、鏈路追蹤、鑒權(quán)等。這些需求可以通過grpc攔截器來實(shí)現(xiàn)。本文使用go語言來實(shí)現(xiàn)個 grpc元模式(Unary)
    的頭像 發(fā)表于 12-18 10:13 ?616次閱讀
    使用go語言實(shí)現(xiàn)<b class='flag-5'>一</b>個grpc<b class='flag-5'>攔截器</b>