Spring MVC学習の概要(9):インターセプターと例外処理

1.インターセプター

1.インターセプターの紹介

Spring MVCのインターセプターは、Javaサーブレットのフィルターに似ており、主にユーザーのリクエストをインターセプトして対応する処理を行うために使用されます。通常、権限の確認、リクエスト情報のログ記録、ユーザーがログインしているかどうかの判断などに使用されます。 。機能的に。Spring MVCフレームワークでインターセプターを定義するには、インターセプターの定義と構成が必要です。インターセプターを定義するには、2つの方法があります。1つはHandlerInterceptorインターフェースまたはHandlerInterceptorインターフェースを継承する実装クラスを実装することによって定義され、もう1つはDefinebyを使用して定義されます。 WebRequestInterceptorインターフェースを実装するか、WebRequestInterceptorインターフェースの実装クラスを継承します。この記事では、2番目の方法で説明します。

HandlerInterceptorには、次の3つのメソッドがあります。

  • preHandleメソッド:このメソッドは、コントローラーの処理要求メソッドの前に実行され、その戻り値は、後続の操作を中断するかどうかを示し、trueを返すと下向きの実行を続行し、falseを返すと後続の操作を中断します。
  • postHandleメソッド:このメソッドは、コントローラーの要求処理メソッドが呼び出された後、ビューが解決される前に実行されます。このメソッドを使用して、要求ドメインのモデルとビューをさらに変更できます。
  • afterCompletionメソッド:このメソッドは、コントローラーの処理要求メソッドの実行後に実行されます。つまり、ビューのレンダリングが終了した後に実行されます。このメソッドは、一部のリソースのクリーンアップとログ情報の記録に使用できます。

インターセプターとフィルターの違いは次のとおりです。

  フィルタ インターセプター
異なる使用範囲 サーブレットの仕様によると、Webプログラムでのみ使用できます。 Webプログラムだけでなく、ApplicaiontおよびSwingプログラムでも使用できます。
異なる仕様 サーブレット仕様の補足。これは、任意のWebプロジェクトで使用できます。 Spring Framework独自の、SpringMVCフレームワークを使用するプロジェクトのみを使用できます
使用されるさまざまなリソース フィルタが機能しない

インターセプターはSpringのコンポーネントであり、Springによって管理され、Springファイルで構成され、サービスオブジェクト、データソース、トランザクション管理など、Springの任意のリソースとオブジェクトを使用できます。

異なる深さ フィルタは、サーブレットの前後でのみ機能します。 インターセプターは、メソッドの前後、例外がスローされる前後に深く入り込むことができ、柔軟性が高くなります。
傍受されたさまざまなリソース / *をurl-patternで構成した後、フィルターはアクセスされるすべてのリソースをブロックします インターセプターはコントローラーメソッドへのアクセスのみをインターセプトします。アクセスがjsp、html、css、image、jsなどの場合、インターセプターはインターセプトされません。

 

2.単一のインターセプターの実行プロセス

構成ファイルでインターセプターが1つだけ定義されている場合、プログラムは最初にインターセプタークラスのpreHandleメソッドを実行します。メソッドがtrueを返す場合、プログラムはコントローラーで要求を処理するメソッドを実行し続けます。それ以外の場合、実行は中断されます。preHandleメソッドがtrueを返し、コントローラーで要求を処理するメソッドが実行されると、ビューが返される前にpostHandleメソッドが実行され、ビューが返された後にafterCompletionメソッドが実行されます。

(1)web.xmlを構成します

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <!--  指定Spring MVC配置文件的位置    -->
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <!--   字符编码过滤器  -->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!--  encoding:指定一个具体的字符集  -->
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <!-- forceEncoding:处理 response中的字符编码  -->
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>

  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>


</web-app>

(2)コントローラークラスを作成する

@Controller
public class InterceptorController {
    @RequestMapping("/testInterceptor")
    public String testInterceptor(){
        System.out.println("我是testInterceptor方法");
        return "interceptorPage";
    }
}

(3)インターセプタークラスを作成する

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("我是preHandle方法---在控制器的处理请求方法调用之后,解析视图之前执行");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("我是postHandle方法---在控制器的处理请求方法调用之后,解析视图之前执行");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("我是afterCompletion方法---在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行");
    }
}

(4)springmvc.xmlでインターセプタークラスを構成します 

    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 配置一个全局拦截器,拦截所有请求 -->
        <mvc:interceptor>
            <!-- 配置拦截器作用的路径 -->
            <mvc:mapping path="/**" />
            <!-- 配置不需要拦截作用的路径 -->
<!--            <mvc:exclude-mapping path="" />-->
            <!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
            <bean class="com.yht.example1.interceptor.MyInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>

上記のサンプルコードでは、<mvc:interceptors>要素を使用してインターセプターのセットを構成し、その子要素<bean>はグローバルインターセプターを定義します。つまり、すべてのリクエストをインターセプトします。

<mvc:interceptor>要素は、指定されたパスのインターセプターを定義し、その子要素<mvc:mapping>は、属性パスで定義されているインターセプターのパスを構成するために使用されます。

上記のサンプルコードのように、パス「/ **」の属性値はすべてのパスをブロックすることを意味し、「/ **」はすべてのパスをブロックすることを意味します。リクエストパスにインターセプトする必要のないコンテンツが含まれている場合は、<mvc:exclude-mapping>サブ要素を使用して構成できます。

<mvc:interceptor>要素の子要素は、<mvc:mapping ... />、<mvc:exclude-mapping ... />、<bean ..の順序で構成する必要があることに注意してください。 />。 

(5)interceptorPage.jspを作成します

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
视图
<%System.out.println("视图渲染结束。"); %>
</body>
</html>

(6)Tomcatサーバーを起動し、アドレス「http:// localhost:8080 / SpringMVCStudy02_war / testInterceptor」を介してインターセプターテストします。出力は次のとおりです。

3.複数のインターセプターの実行プロセス

Webアプリケーションでは、通常、複数のインターセプターが同時に動作する必要があります。このとき、preHandleメソッドは構成ファイル内のインターセプターの構成順に実行され、postHandleメソッドとafterCompletionメソッドはで実行されます。構成順序の逆の順序。以下に示すように:

(1)インターセプタークラスTestInterceptorを作成します。

public class TestInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("我是preHandle方法---TestInterceptor类");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("我是postHandle方法---TestInterceptor类");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("我是afterCompletion方法---TestInterceptor类");
    }
}

(2)springmvc.xmlでTestInterceptorを構成します。

<!-- 配置拦截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 配置拦截器作用的路径 -->
            <mvc:mapping path="/**" />
            <bean class="com.yht.example1.interceptor.MyInterceptor" />
        </mvc:interceptor>
        <mvc:interceptor>
            <!-- 配置拦截器作用的路径 -->
            <mvc:mapping path="/**" />
            <bean class="com.yht.example1.interceptor.TestInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>

(3)Tomcatサーバーを起動し、アドレス「http:// localhost:8080 / SpringMVCStudy02_war / testInterceptor」を介してインターセプターテストします。出力は次のとおりです。

注意:

preHandleでfalseが返された場合は、リリースがないことを意味します。現時点では、request.getRequestDispatcher( "/ WEB-INF / pages / page name")。forward(request、response);を使用してページにジャンプできます。 

2、例外処理

Spring MVCアプリケーションの開発では、基盤となるデータベースの操作であれ、ビジネス層や制御層の操作であれ、対処する必要のあるさまざまな予測可能および予測不可能な例外が必然的に発生します。HandlerExceptionResolverインターフェースは、要求処理中に生成された例外を解決するために使用されます。

(1)カスタム例外クラスSystemException。

public class SystemException extends Exception{
    private String message;

    public SystemException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

(2)ページの下にerror.jspを作成します。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h4>这是错误页面</h4>
${msg}
</body>
</html>

(3)HandlerExceptionResolverインターフェースを実装するSystemExceptionHandlerを作成します

public class SystemExceptionHandler implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        SystemException systemException = null;
        if(e instanceof  SystemException){
            systemException = (SystemException) e;
        }else{
            e = new SystemException("系统异常");
        }
        ModelAndView mv = new ModelAndView();
        mv.setViewName("error");
        mv.addObject("msg", e.getMessage());
        return mv;
    }
}

(4)コントローラーを作成する

@Controller
public class ExceptionController {
    @RequestMapping("/testException")
    public String testException() throws Exception{
        System.out.println("我是testException方法");
        int num = Integer.parseInt("a123");
        return "success";
    }
}

(5)springmvc.xmlでSystemExceptionHandlerを構成します

    <bean class="com.yht.example1.handler.SystemExceptionHandler"></bean>

(6)Tomcatサーバーを起動し、アドレス「http:// localhost:8080 / SpringMVCStudy02_war / testException」を介してインターセプターテストします。インターフェイスの結果は次のとおりです。

おすすめ

転載: blog.csdn.net/weixin_47382783/article/details/113615558