Day71 Spring MVC的攔截器和執行原理

神一樣的我發表於2018-05-10

eclipse部署專案到真實伺服器中

eclipse部署專案到tomcat伺服器目錄中:
        1、  直接在專案上右鍵run on server專案會預設部署到eclipse工作空間中。
            路徑為:
            eclipse工作空間路徑\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps
        2、部署到tomcat自己的目錄中
            雙擊server視窗的伺服器,然後在彈出的頁面中修改部署路徑為tomcat路徑。
            然後將專案部署到tomcat伺服器,啟動專案即可。
注意tomcat是webapps

這裡寫圖片描述
這裡寫圖片描述

springmvc的攔截器

Springmvc的攔截器:
    問題:
        因為處於專案安全形度的考慮,我們需要對請求進行攔截處理。沒有問題才會繼續執行,
    有問題就直接攔截掉。但是,SpringMVC中Servlet只有一個,所以使用過濾器的話,可以實現攔截。
    但是無法實現分層攔截。
    解決: 
        使用SpringMVC的攔截器。
    原理:
        其實就在Servlet和單元方法之間進行攔截。
    使用:
        建立攔截器類
            實現了特殊介面的java類:
            示例:
                package com.bjsxt.intercepter;

import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;



public class MyInter implements HandlerInterceptor{
    /**
     * 
     * preHandle在Servlet之後,單元方法之前執行。
     *  引數:
     *      HttpServletRequest arg0
     *      HttpServletResponse arg1 
     *      Object arg2 引數型別為HandlerMethod,儲存了要執行的單元方法的Method物件。
     *  返回值:    
     *      false 進行攔截,不在繼續執行單元方法
     *      true  放行,繼續執行單元方法。
     *  作用:
     *      攔截單元方法的請求。保護單元方法。
     *  使用:
     *      URL許可權校驗。
     */
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
        System.out.println("MyInter.preHandle()");
        HandlerMethod hm=(HandlerMethod)arg2;
        Method method = hm.getMethod();
        System.out.println(method.getName());
        return true;
    }

    /**
     * postHandle在單元方法之後執行,Jsp之前
     * 引數:
     *      HttpServletRequest arg0, 
     *      HttpServletResponse arg1, 
     *      Object arg2, 引數型別為HandlerMethod,儲存了要執行的單元方法的Method物件。
     *      ModelAndView arg3 儲存了單元方法的返回值以及Model中的資料
     *                       通過此物件可以動態的Model中的資料或者重新跳轉頁面資源。
     * 作用:
     *      在Jsp真的顯示單元方法的處理結果之前,進行校驗。攔截Jsp頁面的內容的。
     */
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView m)
            throws Exception {
        //獲取作用域資料
            Map<String, Object> model = m.getModel();
            String str=(String) model.get("str");
            System.out.println(model.get("str"));
            if(str.contains("中國")){
                str=str.replace("中國", "**");
            }
            m.addObject("str", str);

            System.out.println(m.getViewName());
            //m.setViewName("bb");
        System.out.println("MyInter.postHandle()");

    }
    /**
     * 在Jsp頁面之後執行
     * 引數:
     *      HttpServletRequest arg0, 
     *      HttpServletResponse arg1, 
     *      Object arg2, 
     *      Exception arg3:獲取單元方法的錯誤資訊。
     * 作用:
     *      用來輸出錯誤日誌。
     *      處理單元方法的錯誤資訊。
     */
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        if(arg3!=null){

        }
        System.out.println("MyInter.afterCompletion()");

    }
}
        宣告攔截器的攔截範圍。
            在Springmvc.xml中配置攔截器
            <mvc:interceptors>
                <bean id="my2" class="com.bjsxt.intercepter.MyInter2"></bean><!-- 攔截全部 -->
                <mvc:interceptor>
                    <mvc:mapping path="/demo"/><!--指定攔截  -->
                    <bean id="my" class="com.bjsxt.intercepter.MyInter"></bean>
                </mvc:interceptor>
            </mvc:interceptors>


















SpringMVC的執行原理

SpringMVC學習:
    SpringMVC的配置方式
    SpringMVC獲取請求引數
    SpringMVC的響應
    SpringMVC的上傳下載
    SpringMVC的攔截器
使用SSM框架搭建基本流程:
    匯入jar包
        Mybatis的jar
        Mybatis的依賴Jar
        資料庫jar
        Spring和Mybatis的整合jar
        Spring IOC的jar
        SpringAOP的jar
        SpringTx的jar
        SpringMVC的jar
        Jackson的jar
        jstl的jar
           上傳下載的jar
    配置web.xml
        配置spring相關
        配置SpringMVC相關
        配置編碼過濾器
    在src下建立並配置相關xml檔案
        applicationcontext.xml
            載入Schema
            配置註解掃描
            配置屬性檔案掃描
            配置代理模式
            配置資料來源
            配置工廠
            配置mapper掃描
            配置事務
            配置其他bean
        springmvc.xml
            配置註解掃描
            配置驅動
            配置靜態資源放行(加WEB-INF)
            配置檢視解析器
            配置攔截器
            配置上傳解析bean
            配置異常跳轉bean
    完成程式碼編寫(註解)
        com.bjsxt.controller
        com.bjsxt.service
        com.bjsxt.serviceImpl
        com.bjsxt.mapper
            建立mapper.xml
                配置資料庫操作標籤
                    單表查詢
                    ResultMap多表查詢
                    Sql動態拼接
        com.bjsxt.pojo
        com.bjsxt.intercepter
SpringMVC的執行原理:
        參照word文件
1.核心元件:(SpringMVC 四大元件)
1.1 DispatchServlet: Servlet分發器,整個SPringMVC框架入口.
1.2 HandlerMapping:尋找URL所請求的HandlerMethod,找@RequestMapping()
1.2.1 使用實現類DefaultAnnotationHandlerMapping實際工作.
1.3 HandlerAdapter:實際呼叫HandlerMethod的元件.
1.3.1 使用實現類AnnotationMethodHandlerAdapter
1.4 ViewResovler:檢視解析器.作用解析HandlerMethod返回值.把邏輯檢視轉換為需要呼叫的物理檢視.
1.4.1 自定義時:InternalResourceViewResolver
2.當配置了<mvc:annotation-driven/>時,實際上建立了上面實現類的<bean>物件
3.還可能使用的元件或介面或類:
3.1 Controller : 控制器類
3.2 HandlerMethod: 控制器方法
3.3 View: 檢視
3.4 Model: 模型
3.5 ModelAndView:模型和檢視.SpringMVC所有HandlerMethod最終都會轉換為ModelAndView
3.6 HandlerInterceptor: 攔截器
3.7 HandlerExceptionResolver:異常對映解析器.
3.8 MultipartResolver: Multipart解析器
3.9 CharacterEncodingFilter: 字元編碼過濾器
4.時序圖(Sequence Diagram)
4.1 以時間點作為基本單位,觀察每個時間點狀態.
4.2 具體時序圖

這裡寫圖片描述

文字解釋:

當使用者發起請求後,執行DiapacherServlet,如果是JSP直接呼叫jsp頁面.如果不是JSP,DiapacherServlet呼叫HandlerMapping判斷請求URL是否合法,如果URL不存在報錯,如果URL存在使用HandlerAdapter呼叫具體的HandlerMethod,當Handler執行完成後會返回ModelAndView,會被ViewResovler解析,呼叫具體的物理檢視.
最終響應給客戶端瀏覽器.
這就是SpringMVC執行原理

最新的springmvc.xml和web.xml

加上攔截器(interceptor)的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
        <!--配置註解掃描  -->
        <context:component-scan base-package="com.bjsxt.controller"></context:component-scan>
        <!--配置mvc註解驅動  -->
        <mvc:annotation-driven></mvc:annotation-driven>
        <!--配置靜態資源方式  -->
        <mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
        <mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
        <mvc:resources location="/images/" mapping="/images/**"></mvc:resources>

        <!--配置自定義檢視解析器  -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/email/"></property>
        <property name="suffix" value=".jsp"></property>
        </bean>
        <!--配置攔截器  -->
        <mvc:interceptors>
                <bean id="my2" class="com.bjsxt.intercepter.MyInter2"></bean><!-- 攔截全部 -->
                <mvc:interceptor>
                    <mvc:mapping path="/demo"/><!--指定攔截  -->
                    <bean id="my" class="com.bjsxt.intercepter.MyInter"></bean>
                </mvc:interceptor>
            </mvc:interceptors>
        <!--配置上傳資源解析物件  -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"></property>
        <property name="maxInMemorySize" value="150000"></property>
        <property name="maxUploadSize" value="1024123123"></property>
        </bean>
        <!--配置異常解析器  -->
        <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
        <props>
        <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">sizeLimit</prop>
        </props>
        </property>
        </bean>
        </beans>


web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <!--配置Spring  -->
  <!--配置applicationContext,xml的路徑  -->
  <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!--配置監聽器  -->
  <listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
  <!--配置SpringMVC 的servlet  -->
  <servlet>
    <servlet-name>servlet123</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置Spring MVC 的配置檔案路徑  -->
    <init-param>
    <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>servlet123</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <!--配置編碼過濾器  -->
  <filter>
  <filter-name>encoding</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
  <param-name>encoding</param-name>
  <param-value>utf-8</param-value>
  </init-param>
  <init-param>
 <param-name>forceEncoding</param-name>
 <param-value>true</param-value>
 </init-param>
  </filter>
  <filter-mapping>
  <filter-name>encoding</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

路徑問題總結

路徑問題總結:
    前端:
        如果Jsp頁面中的靜態資源路徑使用相對路徑,因為路徑時相對當次請求地址來進行資源查詢的。
        有可能會出現資源找不到的情況。
        使用絕對路徑:
            在Jsp頁面中靜態資源的路徑中的/表示伺服器根目錄。需要寫成
            /專案名/資源路徑
        示例:
            <script type="text/javascript" src="/專案名/js/a.js"></script>
            <img src="/專案名/images/a.jpg" alt="" />
            <link rel="stylesheet" type="text/css" href="/專案名/css/a.css" />
    後臺:
        在後臺中/表示專案根目錄。
        在單元方法中,返回值中最好都加上/

能力提升


<!--配置SpringMVC 的servlet  -->
  <servlet>
    <servlet-name>servlet123</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 </servlet>
  <servlet-mapping>
    <servlet-name>servlet123</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

/ 表示除了jsp什麼都攔截
/* 表示什麼都攔截
/*.do  表示攔截以.do結尾的請求。

實現線上人數:
https://blog.csdn.net/wdehxiang/article/details/77461378
攔截器實現許可權校驗:
https://blog.csdn.net/tonytfjing/article/details/39207551
https://blog.csdn.net/IT_LOSER/article/details/52859711


登入攔截空指標問題

小結

eclipse部署專案到真實伺服器中
springmvc的攔截器
SpringMVC的執行原理
最新的springmvc.xml和web.xml
路徑問題總結
能力提升

相關文章