SpringBoot統合処理機能の実装方法

WBOY
リリース: 2023-05-11 16:04:06
転載
1305 人が閲覧しました

ネットワークリクエストを処理する場合、一部の機能はビジネスから分離して抽出して均一に処理する必要があります。

ログイン検証

Spring mvc のインターセプター Interceptor を使用して HandlerInterceptor インターフェースを実装できます。このインターフェイスを実装した後、リクエストはコントローラーに送信される前にインターセプトされます。

インターセプターの実装は、次の 2 つのステップに分かれています。

  • カスタム インターセプターを作成し、HandlerInterceptor インターフェイスの preHandle を実装します (メソッドを実行する前に pre-Handle を実行します)。具体的な方法)処理)方法。

  • カスタム インターセプターを WebMvcConfigurer の addInterceptors メソッドに追加します。

ログイン検証の例としてセッションを使用します。実装は次のとおりです:

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 则不能继续往下执行;为 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("当前用户没有访问权限");
        response.setStatus(401);
        return false;
    }
}
ログイン後にコピー

WebMvcConfigurer を介して作成されたカスタム インターセプターをコンテナに登録し、インターセプトを有効にします。実装コードは次のとおりです。

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("/**") // 拦截所有请求
                .excludePathPatterns("/user/login"); // 排除不拦截的 url
    }
}
ログイン後にコピー

オブジェクトが挿入されていない場合は、addInterceptor() のパラメータで新しいオブジェクトを直接作成することもできます。

@Configuration // 一定不要忘记
public class MyConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") // 拦截所有请求
                .excludePathPatterns("/user/login"); // 排除不拦截的 url
    }
}
ログイン後にコピー

Principle

すべてのコントローラ実行は、Spring mvc スケジューラ DispatcherServlet を通じて実装されます。すべてのメソッドは、DispatcherServlet の doDispatch スケジューリング メソッドを実行します。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 {
                // ...  忽略不重要的代码
                // 调⽤预处理
                if (!mappedHandler.applyPreHandle(processedRequest, respon
                        se)) {
                    return;
                }
                // 执⾏ Controller 中的业务
                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);
        }
    }
}
ログイン後にコピー

上記のソース コードから、実行を開始する前に次のことがわかります。 Controller を実行すると、前処理メソッド applyPreHandle が最初に呼び出されます。 applyPreHandle メソッドの実装ソース コードは次のとおりです。

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex
            = i++) {
        // 获取项⽬中使⽤的拦截器 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;
}
ログイン後にコピー

例外処理

リクエスト中の例外処理も比較的一般的です。統一処理の対象。

統一例外処理は、@ControllerAdvice @ExceptionHandler を使用して実装されます。@ControllerAdvice はコントローラー通知クラスを表し、@ExceptionHandler は例外ハンドラーです。この 2 つの組み合わせは、例外が発生したときに特定の関数を実行することを意味します。つまり、特定のメソッド イベントの実行の具体的な実装コードは次のとおりです。

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;
/**
 * 统一处理异常
 * 一般都需要自定义一个异常对象,这里为了简单说明只用一个map对象来说明
 */
@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;
    }
}
ログイン後にコピー

この時点で例外が発生した場合、エラーは報告されず、コードは引き続き実行されますが、カスタマイズされた例外情報はフロントエンドに返されます。

Principle

@ControllerAdvice は、組み込む必要があるエントリ ポイントやスライス ロジックを含む、コントローラーのすべての属性をスライスする Spring の AOP で、@ExceptionHandler と連携して、スローされた指定された型をキャプチャします。異なる種類の例外を異なる方法で処理するという目的を達成するために、コントローラーで例外を処理します。

戻りデータ構造

統一された戻りデータ構造は、@ControllerAdvice ResponseBodyAdvice インターフェイスを使用して実装できます。具体的な実装コードは次のとおりです:

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;
/**
 * 统一返回数据的处理
 */
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    /**
     * 内容是否需要重写(通过此⽅法可以选择性部分控制器和⽅法进⾏重写)
     * 返回 true 表示重写
     */
    @Override
    public boolean supports(MethodParameter returnType, Class converterTyp
e) {
        return true;
    }
    /**
     * ⽅法返回之前调⽤此⽅法
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class selectedConverterType, ServerHttpR
                                          equest request,
                                  ServerHttpResponse response) {
        // 构造统⼀返回对象
        HashMap<String, Object> result = new HashMap<>();
        result.put("state", 1);
        result.put("msg", "");
        result.put("data", body);
        return result;
    }
}
ログイン後にコピー

以上がSpringBoot統合処理機能の実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート