最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實(shí)現(xiàn)統(tǒng)一功能處理的教程詳解

 更新時(shí)間:2023年05月30日 10:10:37   作者:YoLo?  
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何實(shí)現(xiàn)統(tǒng)一功能處理,文中的示例代碼講解詳細(xì),對(duì)大家學(xué)習(xí)或工作有一定借鑒價(jià)值,感興趣的同學(xué)可以參考閱讀下

實(shí)現(xiàn)三個(gè)SpringBoot統(tǒng)一功能處理

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

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

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

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

之前的博客系統(tǒng)中,我們在每個(gè)頁面都要檢查用戶是否登錄,之后才有權(quán)限去做其他操作,之前的判斷方式就是,需要驗(yàn)權(quán)的每一處都寫了相同的驗(yàn)證方法.業(yè)務(wù)代碼中夾雜了這些非業(yè)務(wù)的代碼

現(xiàn)在我們提供一個(gè)公共的AOP方法來進(jìn)行統(tǒng)一的用戶登陸權(quán)限驗(yàn)證

在AOP的切面中實(shí)現(xiàn)用戶登陸權(quán)限的校驗(yàn)功能非常麻煩

Spring中提供了具體的實(shí)現(xiàn)攔截器:HandlerInterceptor

攔截器的實(shí)現(xiàn):

WebMvcConfigurer+HandlerInterceptor

1.1.創(chuàng)建自定義攔截器

創(chuàng)建一個(gè) Java 類,并實(shí)現(xiàn) HandlerInterceptor 接口,該接口有三個(gè)方法:preHandle、postHandle 和 afterCompletion。在 preHandle 方法中編寫前置處理邏輯,在 postHandle 方法中編寫后置處理邏輯,在 afterCompletion 方法中編寫完成后的處理邏輯

此方法返回的是布爾類型的值,返回true表示攔截器驗(yàn)證成功,繼續(xù)執(zhí)行目標(biāo)方法

返回false,則表示攔截器執(zhí)行失敗,驗(yàn)證不通過,后續(xù)目標(biāo)方法不會(huì)執(zhí)行

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //用戶登錄判斷的業(yè)務(wù)
        HttpSession session = request.getSession(false);
        if(session!=null && session.getAttribute("session_userinfo")!=null){
            //用戶登陸成功
            return true;
        }
        //response.sendRedirect("http://www.baidu.com");跳轉(zhuǎn)頁面
        //response.setStatus(401);沒有權(quán)限
        return false;
    }
}

2.將自定義攔截器配置到系統(tǒng)配置項(xiàng),并設(shè)置攔截規(guī)則

代碼

@Configuration
public class MyConfig implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")//攔截所有的url
                .excludePathPatterns("/user/login")//排除登陸功能
                .excludePathPatterns("/user/reg")//排除注冊功能
                .excludePathPatterns("/image/**")//排除image下所有的文件
                ;
    }
}

對(duì)如下代碼測試

這里登陸失敗后由于將狀態(tài)設(shè)置為了401,所以網(wǎng)頁無法正常運(yùn)作了

正常的應(yīng)該是,返回檢驗(yàn)登陸失敗的信息,讓用戶從前端了解情況

有了攔截器之后,會(huì)在調(diào)用Controller之前進(jìn)行攔截器的預(yù)處理操作

執(zhí)行流程:用戶->攔截器->controller->service->mapper->database

下來我們分析源碼

所有的Controller執(zhí)行都會(huì)通過一個(gè)DispatcherServlet來實(shí)現(xiàn),可以從打印臺(tái)看出

DispatcherServlet是SpringMVC框架的核心,主要負(fù)責(zé)管理請(qǐng)求和處理器之間的映射關(guān)系,并結(jié)合所配置的攔截器和視圖解析器來實(shí)現(xiàn)請(qǐng)求的分發(fā)和結(jié)果的呈現(xiàn)

例如:攔截器:DispatcherServlet支持對(duì)請(qǐng)求進(jìn)行攔截,并允許用戶定義自己的攔截器來進(jìn)行請(qǐng)求處理前和處理后的操作

大致流程如下 

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

如果不進(jìn)行統(tǒng)一異常處理,出現(xiàn)異常,會(huì)直接將異常拋到前端

統(tǒng)一的異常處理使用的是@ControllerAdvice和@ExceptionHandler來實(shí)現(xiàn)的

@ControllerAdvice表示控制器通知類,@ExceptionHandler是異常處理器,兩者結(jié)合表示出現(xiàn)異常時(shí)執(zhí)行某個(gè)通知

1.建立異常處理類

添加該注解可以集中處理所有 Controller 中拋出的異常,從而避免開發(fā)人員在每個(gè) Controller 中都編寫異常處理代碼的重復(fù)勞動(dòng)

2.創(chuàng)建異常檢測的類和業(yè)務(wù)處理方法

@ControllerAdvice 可以定義一些方法,在方法內(nèi)部使用 @ExceptionHandler 注解來處理指定類型的異常。當(dāng) Controller 中拋出該類型的異常時(shí),就會(huì)自動(dòng)調(diào)用相應(yīng)的方法來處理異常,而不是直接將異常拋到前端

此時(shí)就會(huì)返回一個(gè)json格式的異常信息到前端 

上述只是處理了空指針異常,其它異常是攔截不到的.所以將監(jiān)視異常的范圍擴(kuò)大,出現(xiàn)各種異常,就會(huì)找到它們的父類--Exception

添加一個(gè)異常代碼 

如果實(shí)現(xiàn)了具體的異常類,也實(shí)現(xiàn)了Exception.那么默認(rèn)是匹配具體的異常處理,匹配不到就會(huì)尋找父類的處理

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

統(tǒng)一數(shù)據(jù)格式返回是指在 Spring MVC 中,定義一個(gè)通用的數(shù)據(jù)結(jié)構(gòu),來封裝所有接口的返回值,這樣可以更好地對(duì)所有返回結(jié)果進(jìn)行統(tǒng)一處理和管理,從而提高代碼的可維護(hù)性、可重用性和可擴(kuò)展性

使用注解@ControllerAdvice+ResponseBodyAdvice接口

步驟:

1.創(chuàng)建一個(gè)類,并添加 @ControllerAdvice 注解,該注解作用于類上,表示這是一個(gè)全局控制器增強(qiáng)器

2.實(shí)現(xiàn) ResponseBodyAdvice 接口,并指定泛型 T 為 Object 類型。該接口中定義了兩個(gè)方法 beforeBodyWrite() 和 supports(),分別用于處理響應(yīng)前的操作和判斷是否支持當(dāng)前返回值類型

3.在 beforeBodyWrite() 方法中,判斷響應(yīng)的對(duì)象是否為自定義的統(tǒng)一數(shù)據(jù)格式返回類型,如果不是,則將它轉(zhuǎn)換成統(tǒng)一的格式,例如封裝成一個(gè) Result 對(duì)象

4.在 supports() 方法中,判斷當(dāng)前返回值類型是否需要進(jìn)行統(tǒng)一數(shù)據(jù)格式返回的處理

使用該方法后,所有返回類型為非基本數(shù)據(jù)類型的請(qǐng)求,都會(huì)經(jīng)過 ResponseBodyAdvice 的處理,從而統(tǒng)一返回給前端一個(gè)自定義的結(jié)構(gòu)體數(shù)據(jù) 

@ControllerAdvice
public class ResponseBody implements ResponseBodyAdvice {
    //是否執(zhí)行beforeBodyWrite,true為執(zhí)行
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }
    //返回?cái)?shù)據(jù)之前進(jìn)行數(shù)據(jù)重寫
    //body:原始返回值
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        //標(biāo)準(zhǔn)返回格式定義為:HashMap<String,Object>->code,msg,data
        if(body instanceof HashMap){
            return body;
        }
        //重寫返回結(jié)果,返回統(tǒng)一格式
        HashMap<String,Object> res = new HashMap<>();
        res.put("code",200);
        res.put("msg","");
        res.put("data",body);
        return res;
    }
}

login:

reg: 

按照保底的數(shù)據(jù)返回格式應(yīng)該返回data為sayhello

Resolved [java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String]

將String格式化數(shù)據(jù)執(zhí)行流程分為三部

1.方法返回String

2.統(tǒng)一數(shù)據(jù)格式返回之前處理:String轉(zhuǎn)換為Hash Map

3.將Hash Map轉(zhuǎn)換為application/json 字符串返回給前端(接口)

 不進(jìn)行異常攔截時(shí): 

通過報(bào)錯(cuò)信息,可以看出是第三步出了問題,無法將HashMap 轉(zhuǎn)換為json字符串

原因:在第三步會(huì)對(duì)原body類型進(jìn)行判斷

1.String類型:使用StringHttpMessageConverter轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換

2.非string類型:HttpMessageConverter轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換

使用的卻是StringHttpMessageConverter轉(zhuǎn)換器對(duì)HashMap轉(zhuǎn)換成json字符串.就會(huì)拋出異常

應(yīng)當(dāng)適用HttpMessageConverter

判斷時(shí)使用原body進(jìn)行判斷,轉(zhuǎn)換時(shí)使用的是Hash Map進(jìn)行轉(zhuǎn)換的..StringHttpMessageConverter轉(zhuǎn)換不了Hash Map

解決方案:

1. 移除StringHttpMessageConverter

通過config配置文件移除

@Configuration
public class MyConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.removeIf(converter -> converter instanceof StringHttpMessageConverter);
    }
}

2.統(tǒng)一數(shù)據(jù)重寫時(shí)單獨(dú)處理String類型,單獨(dú)返回,不使用Hash Map進(jìn)行統(tǒng)一返回

方式一:

方式二:使用json工具轉(zhuǎn)換

以上就是SpringBoot實(shí)現(xiàn)統(tǒng)一功能處理的教程詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot統(tǒng)一功能處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springcloud feign docker上無法通訊的問題及解決

    springcloud feign docker上無法通訊的問題及解決

    這篇文章主要介紹了springcloud feign docker上無法通訊的問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • ConcurrentHashMap原理及使用詳解

    ConcurrentHashMap原理及使用詳解

    ConcurrentHashMap是Java中的一種線程安全的哈希表實(shí)現(xiàn),它提供了與Hashtable和HashMap類似的API,是一個(gè)高效且可靠的多線程環(huán)境下的哈希表實(shí)現(xiàn),非常適合在并發(fā)場景中使用,本文就簡單介紹一下ConcurrentHashMap原理及使用,需要的朋友可以參考下
    2023-06-06
  • RocketMQ中的消費(fèi)模式和消費(fèi)策略詳解

    RocketMQ中的消費(fèi)模式和消費(fèi)策略詳解

    這篇文章主要介紹了RocketMQ中的消費(fèi)模式和消費(fèi)策略詳解,RocketMQ 是基于發(fā)布訂閱模型的消息中間件,所謂的發(fā)布訂閱就是說,consumer 訂閱了 broker 上的某個(gè) topic,當(dāng) producer 發(fā)布消息到 broker 上的該 topic 時(shí),consumer 就能收到該條消息,需要的朋友可以參考下
    2023-10-10
  • java中HttpClient使用方法舉例詳解

    java中HttpClient使用方法舉例詳解

    這篇文章主要介紹了java中HttpClient使用方法的相關(guān)資料,HttpClient提供了發(fā)送HTTP請(qǐng)求和接收HTTP響應(yīng)的功能,簡化了HTTP通信的處理,減少了對(duì)外部庫的依賴,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-12-12
  • Springboot 如何使用@Async整合線程池

    Springboot 如何使用@Async整合線程池

    這篇文章主要介紹了Springboot 使用@Async整合線程池的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java 文件上傳與路徑處理之Paths.get()、resolve()、transferTo()的用法詳解

    Java 文件上傳與路徑處理之Paths.get()、resolve()、transferTo()的用法詳解

    本文詳細(xì)解析了如何使用Java的Paths.get()、resolve()和Spring的transferTo()方法處理文件上傳功能,并給出了完整的代碼示例,感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • Java歐拉函數(shù)的計(jì)算代碼詳解

    Java歐拉函數(shù)的計(jì)算代碼詳解

    這篇文章主要介紹了Java實(shí)現(xiàn)歐拉函數(shù)的計(jì)算,從歐拉函數(shù)引伸出來在環(huán)論方面的事實(shí)和拉格朗日定理構(gòu)成了歐拉定理的證明,本文通過實(shí)例代碼給大家介紹的很詳細(xì),需要的朋友可以參考下
    2021-05-05
  • SpringBoot配置項(xiàng)目訪問路徑URL的根路徑方式

    SpringBoot配置項(xiàng)目訪問路徑URL的根路徑方式

    這篇文章主要介紹了SpringBoot配置項(xiàng)目訪問路徑URL的根路徑方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 淺談MyBatis-Plus學(xué)習(xí)之Oracle的主鍵Sequence設(shè)置的方法

    淺談MyBatis-Plus學(xué)習(xí)之Oracle的主鍵Sequence設(shè)置的方法

    這篇文章主要介紹了淺談MyBatis-Plus學(xué)習(xí)之Oracle的主鍵Sequence設(shè)置的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Sleuth+logback 設(shè)置traceid 及自定義信息方式

    Sleuth+logback 設(shè)置traceid 及自定義信息方式

    這篇文章主要介紹了Sleuth+logback 設(shè)置traceid 及自定義信息方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論

大安市| 远安县| 塔河县| 涿鹿县| 天全县| 玛曲县| 洞口县| 南丹县| 余江县| 阿拉善盟| 安西县| 江陵县| 如皋市| 临沧市| 昔阳县| 安康市| 什邡市| 彭州市| 巴林左旗| 兴安盟| 景德镇市| 河源市| 垣曲县| 翼城县| 南投县| 鄄城县| 敦煌市| 永兴县| 稷山县| 时尚| 麦盖提县| 毕节市| 柳江县| 朝阳区| 石棉县| 龙游县| 潞西市| 准格尔旗| 新和县| 蒲江县| 屯门区|