亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot統(tǒng)一處理功能實(shí)現(xiàn)的全過(guò)程

 更新時(shí)間:2023年03月20日 09:17:29   作者:我叫小八  
最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,主要是一些分類入庫(kù)以及記錄日志等,下面這篇文章主要給大家介紹了關(guān)于SpringBoot統(tǒng)一功能處理實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

在處理網(wǎng)絡(luò)請(qǐng)求時(shí),有一部分功能是需要抽出來(lái)統(tǒng)一處理的,與業(yè)務(wù)隔開。

登錄校驗(yàn)

可以利用spring mvc的攔截器Interceptor,實(shí)現(xiàn)HandlerInterceptor接口即可。實(shí)現(xiàn)該接口后,會(huì)在把請(qǐng)求發(fā)給Controller之前進(jìn)行攔截處理。

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

  • 創(chuàng)建?定義攔截器,實(shí)現(xiàn) HandlerInterceptor 接?的 preHandle(執(zhí)?具體?法之前的預(yù)處理)?法。
  • 將?定義攔截器加? WebMvcConfigurer 的 addInterceptors ?法中。

我們使用session來(lái)作為登錄校驗(yàn)的例子,實(shí)現(xiàn)如下:

package com.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
 * 登錄攔截器
 */
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 為 false 則不能繼續(xù)往下執(zhí)行;為 true 則可以。
     */ 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 判斷session的信息是否合法
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute("userinfo") != null) {
            return true;
        }
        log.error("當(dāng)前用戶沒有訪問(wèn)權(quán)限");
        response.setStatus(401);
        return false;
    }
}

將寫好的?定義攔截器通過(guò)WebMvcConfigurer注冊(cè)到容器中,使得攔截器生效,具體實(shí)現(xiàn)代碼如下:

package com.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyConfig implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**") // 攔截所有請(qǐng)求
                .excludePathPatterns("/user/login"); // 排除不攔截的 url
    }
}

如果不注入對(duì)象的話,addInterceptor() 的參數(shù)也可以直接 new 一個(gè)對(duì)象:

@Configuration // 一定不要忘記
public class MyConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") // 攔截所有請(qǐng)求
                .excludePathPatterns("/user/login"); // 排除不攔截的 url
    }
}

原理

所有的 Controller 執(zhí)?都會(huì)通過(guò)spring mvc的調(diào)度器 DispatcherServlet 來(lái)實(shí)現(xiàn),所有?法都會(huì)執(zhí)? DispatcherServlet 中的 doDispatch 調(diào)度?法,doDispatch 源碼如下:

protected void doDispatch(HttpServletRequest request, HttpServletResponse
        response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    try {
        try {
            ModelAndView mv = null;
            Object dispatchException = null;
            try {
                // ...  忽略不重要的代碼
                // 調(diào)?預(yù)處理
                if (!mappedHandler.applyPreHandle(processedRequest, respon
                        se)) {
                    return;
                }
                // 執(zhí)? Controller 中的業(yè)務(wù)
                mv = ha.handle(processedRequest, response, mappedHandler.g
                        etHandler());
               // ...  忽略不重要的代碼
            } catch (Exception var20) {
                dispatchException = var20;
            } catch (Throwable var21) {
                dispatchException = new NestedServletException("Handler di
                        spatch failed", var21);
            }
            this.processDispatchResult(processedRequest, response, mappedH
                    andler, mv, (Exception)dispatchException);
        } catch (Exception var22) {
            this.triggerAfterCompletion(processedRequest, response, mapped
                    Handler, var22);
        } catch (Throwable var23) {
            this.triggerAfterCompletion(processedRequest, response, mapped
                    Handler, new NestedServletException("Handler processing failed", var23));
        }
    } finally {
        if (asyncManager.isConcurrentHandlingStarted()) {
            if (mappedHandler != null) {
                mappedHandler.applyAfterConcurrentHandlingStarted(processe
                        dRequest, response);
            }
        } else if (multipartRequestParsed) {
            this.cleanupMultipart(processedRequest);
        }
    }
}

從上述源碼可以看出在開始執(zhí)? Controller 之前,會(huì)先調(diào)? 預(yù)處理?法 applyPreHandle,? applyPreHandle ?法的實(shí)現(xiàn)源碼如下:

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex
            = i++) {
        // 獲取項(xiàng)?中使?的攔截器 HandlerInterceptor
        HandlerInterceptor interceptor = (HandlerInterceptor)this.intercep
        torList.get(i);
        if (!interceptor.preHandle(request, response, this.handler)) {
            this.triggerAfterCompletion(request, response, (Exception)null
            );
            return false;
        }
    }
    return true;
}

異常處理

請(qǐng)求時(shí)的異常處理也是比較常見的統(tǒng)一處理的對(duì)象。

統(tǒng)?異常處理使?的是 @ControllerAdvice + @ExceptionHandler 來(lái)實(shí)現(xiàn)的,@ControllerAdvice 表示控制器通知類,@ExceptionHandler 是異常處理器,兩個(gè)結(jié)合表示當(dāng)出現(xiàn)異常的時(shí)候執(zhí)?某個(gè)通知,也就是執(zhí)?某個(gè)?法事件,具體實(shí)現(xiàn)代碼如下:

package com.demo;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
/**
 * 統(tǒng)一處理異常
 * 一般都需要自定義一個(gè)異常對(duì)象,這里為了簡(jiǎn)單說(shuō)明只用一個(gè)map對(duì)象來(lái)說(shuō)明
 */
@ControllerAdvice
public class ErrorAdive {
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public HashMap<String, Object> exceptionAdvie(Exception e) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("code", "-1");
        result.put("msg", e.getMessage());
        return result;
    }
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public HashMap<String, Object> arithmeticAdvie(ArithmeticException e) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("code", "-2");
        result.put("msg", e.getMessage());
        return result;
    }
}

此時(shí)若出現(xiàn)異常就不會(huì)報(bào)錯(cuò)了,代碼會(huì)繼續(xù)執(zhí)行,但是會(huì)把自定義的異常信息返回給前端!

原理

@ControllerAdvice是spring的aop對(duì)于Controller進(jìn)行切面所有屬性的,包括切入點(diǎn)和需要織入的切面邏輯,配合@ExceptionHandler來(lái)捕獲Controller中拋出的指定類型的異常,從而達(dá)到不同類型的異常區(qū)別處理的目的。

返回?cái)?shù)據(jù)結(jié)構(gòu)

統(tǒng)?的返回?cái)?shù)據(jù)結(jié)構(gòu)可以使用 @ControllerAdvice + ResponseBodyAdvice接口 的方式實(shí)現(xiàn),具體實(shí)現(xiàn)代碼如下:

package com.demo;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyA
dvice;
import java.util.HashMap;
/**
 * 統(tǒng)一返回?cái)?shù)據(jù)的處理
 */
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    /**
     * 內(nèi)容是否需要重寫(通過(guò)此?法可以選擇性部分控制器和?法進(jìn)?重寫)
     * 返回 true 表示重寫
     */
    @Override
    public boolean supports(MethodParameter returnType, Class converterTyp
e) {
        return true;
    }
    /**
     * ?法返回之前調(diào)?此?法
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class selectedConverterType, ServerHttpR
                                          equest request,
                                  ServerHttpResponse response) {
        // 構(gòu)造統(tǒng)?返回對(duì)象
        HashMap<String, Object> result = new HashMap<>();
        result.put("state", 1);
        result.put("msg", "");
        result.put("data", body);
        return result;
    }
}

到此這篇關(guān)于SpringBoot統(tǒng)一處理功能實(shí)現(xiàn)的全過(guò)程的文章就介紹到這了,更多相關(guān)SpringBoot統(tǒng)一處理功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud中的Feign服務(wù)間的調(diào)用詳解

    SpringCloud中的Feign服務(wù)間的調(diào)用詳解

    這篇文章主要介紹了SpringCloud中的Feign服務(wù)間的調(diào)用詳解,Feign 是一個(gè)聲明式的 REST 客戶端,它能讓 REST 調(diào)用更加簡(jiǎn)單,Feign 供了 HTTP 請(qǐng)求的模板,通過(guò)編寫簡(jiǎn)單的接口和插入注解,就可以定義好 HTTP 請(qǐng)求的參數(shù)、格式、地址等信息,需要的朋友可以參考下
    2024-01-01
  • JVM中對(duì)象的創(chuàng)建與OOP-Klass模型

    JVM中對(duì)象的創(chuàng)建與OOP-Klass模型

    這篇文章主要介紹了JVM中對(duì)象的創(chuàng)建與OOP-Klass模型,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java遞歸方法實(shí)現(xiàn)山脈繪制

    Java遞歸方法實(shí)現(xiàn)山脈繪制

    這篇文章主要為大家詳細(xì)介紹了Java遞歸方法實(shí)現(xiàn)山脈繪制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • @Async異步線程池以及線程的命名方式

    @Async異步線程池以及線程的命名方式

    這篇文章主要介紹了@Async異步線程池以及線程的命名方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • SpringBoot+SpringSecurity實(shí)現(xiàn)基于真實(shí)數(shù)據(jù)的授權(quán)認(rèn)證

    SpringBoot+SpringSecurity實(shí)現(xiàn)基于真實(shí)數(shù)據(jù)的授權(quán)認(rèn)證

    Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問(wèn)控制框架,Spring Security主要做兩個(gè)事情,認(rèn)證、授權(quán)。這篇文章主要介紹了SpringBoot+SpringSecurity實(shí)現(xiàn)基于真實(shí)數(shù)據(jù)的授權(quán)認(rèn)證,需要的朋友可以參考下
    2021-05-05
  • Spring Security入門demo案例

    Spring Security入門demo案例

    Spring Security是一個(gè)高度自定義的安全框架,本文主要介紹了Spring Security入門,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • JAVA基礎(chǔ) 語(yǔ)句標(biāo)簽的合法使用,以及{}語(yǔ)句塊到底有什么用?

    JAVA基礎(chǔ) 語(yǔ)句標(biāo)簽的合法使用,以及{}語(yǔ)句塊到底有什么用?

    以前的一個(gè)思維誤區(qū),for(){},if(){}之類的用法中,邏輯if()和語(yǔ)句塊{}應(yīng)該是相互獨(dú)立的兩種語(yǔ)法
    2012-08-08
  • Java中的隨機(jī)數(shù)Random

    Java中的隨機(jī)數(shù)Random

    這篇文章主要介紹了Java中的隨機(jī)數(shù)Random,關(guān)于隨機(jī)數(shù)的介紹不設(shè)置隨機(jī)數(shù)種子,你每次隨機(jī)抽樣得到的數(shù)據(jù)都是不一樣的。設(shè)置了隨機(jī)數(shù)種子,能夠確保每次抽樣的結(jié)果一樣,下面來(lái)了解具體的詳細(xì)內(nèi)容介紹吧
    2022-03-03
  • 兩種java實(shí)現(xiàn)二分查找的方式

    兩種java實(shí)現(xiàn)二分查找的方式

    這篇文章主要給大家分享的是java實(shí)現(xiàn)二分查找的方式,二分查找是一種查詢效率非常高的查找算法。又稱折半查找。下面文章我們介紹了兩種方法,需要的朋友可以參考一下
    2021-09-09
  • Springboot項(xiàng)目通過(guò)redis實(shí)現(xiàn)接口的冪等性

    Springboot項(xiàng)目通過(guò)redis實(shí)現(xiàn)接口的冪等性

    這篇文章主要為大家介紹了Springboot項(xiàng)目通過(guò)redis實(shí)現(xiàn)接口的冪等性,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12

最新評(píng)論