spring的一個小例子(二)--解析前面的小例子

来源:http://www.cnblogs.com/xuejupo/archive/2016/03/07/5252009.html
-Advertisement-
Play Games

這是對前一個spring小例子的解析


        接上篇:http://www.cnblogs.com/xuejupo/p/5236448.html

        首先應該明白,一個web項目,web.xml是入口。

        然後下麵來分析上篇博客中出現的web.xml:

<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
    version="2.5">  
    <!-- 區分項目名稱,防止預設重名 -->    
    <context-param>    
        <param-name>webAppRootKey</param-name>    
        <param-value>maven.cainiao.root</param-value>    
    </context-param>    
    
    <!-- Spring的log4j監聽器 -->    
    <listener>    
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>    
    </listener>    
    
    <!-- 字元集 過濾器  -->    
    <filter>    
        <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>    
        <url-pattern>/*</url-pattern>    
    </filter-mapping>    
    
    <!-- Spring view分發器 -->    
    <servlet>    
        <servlet-name>dispatcher_cainiao</servlet-name>    
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    
        <init-param>    
            <param-name>contextConfigLocation</param-name>    
            <param-value>/WEB-INF/dispatcher_cainiao.xml</param-value>    
        </init-param>    
        <load-on-startup>1</load-on-startup>    
    </servlet>
    <servlet-mapping>    
        <servlet-name>dispatcher_cainiao</servlet-name>    
        <url-pattern>/</url-pattern>    
    </servlet-mapping>    
</web-app> 

         首先是context-param參數,說context-param之前,應該有個概念:

         web.xml的載入過程是context-param -> listener  -> fileter  -> servlet。

         context-param屬性在xml文件里是最先被載入的,但是只有他是然並卵的,他必須配合別的java類一起使用。context-param差不多就相當於一個web項目的內置map,key和value都是String,context-param的載入只是為這個map賦值,相當於配置參      數,讓之後的監聽或者過濾器等能夠使用context-param中配置好的參數。

           舉個例子,我的web伺服器是jboss,在context-param中配置參數

<context-param>    
        <param-name>webAppRootKey</param-name>    
        <param-value>maven.cainiao.root</param-value>    
    </context-param>

後,jboss在載入這個項目的時候這個項目的別名就是maven.cainiao.root。這時候,如果在jboss中有別的項目也叫這個名字,那麼jboss就會報錯。

      再比如說,如果要設定日誌監聽,就要在context-param中配置log4jConfigLocation參數,log監聽器Log4jConfigListener會在載入的時候自動監聽log4jConfigLocation參數對應的值下的文件;再比如,ContextLoaderListener監聽器負責將contextConfigLocation參數路徑下的xml文件載入。

      當然,也可以自己做監聽或者過濾器,然後在web.xml中通過context-param配置過濾的參數(通過ServletConfig.getInitParameter(key))。

      然後就是org.springframework.web.util.Log4jConfigListener,這是一個spring的log4j監聽器。實際上我們不實用這個監聽也是可以的,但是使用它有幾個好處:

      首先如果不用他,那麼log的配置文件log4j.properties必須寫在classpath下,而用它的話,你就可以很方便得管理log4j.properties的位置了。

      其次,這個監聽中有個方法會每隔60秒掃描log4j配置文件,這樣修改log4j配置文件就可以不用重啟服務了。

      再然後,字元過濾器CharacterEncodingFilter,可以看到filter-mapping中的url-pattern是/*,他負責將/*(也就是全部路徑)下的所有請求,強制轉換為UTF-8編碼的形式,這樣如果在編寫頁面的時候也用utf-8

編碼,就可以防止亂碼的產生了。

      最後就是跟我們打交道最多的servlet了。首先看servlet-mapping,這裡有個url-pattern,這裡匹配url里輸入的,比如說上面的web.xml中這裡是/,那麼,所有的http://localhost:8080/test/*的url都會被這個名字叫做dispatcher_cainiao的servlet解析。servlet-mapping下的servlet-name對應servlet下的servlet-name,根據name找到具體的servlet(servlet-mapping是servlet的入口,感覺更像是介面,負責servlet的入口url和對應具體的servlet實現類);而這個servlet-class,就是具體的servlet實現類了。當然,我們可以寫自己的實現類,這樣url就會請求到我們自己的servlet里(現在已經很少有這種寫法了),還可以交給spring托管,比如實現類寫org.springframework.web.servlet.DispatcherServlet,這是spring框架中的一個流程式控制制器,負責分發url。init-param表示將初始化他的配置參數,如上面的配置中,這個分發器使用的配置文件路徑為:/WEB-INF/dispatcher_cainiao.xml,load-on-startup表示他在web容易啟動的時候會自載入(這個很重要,不加這個你的url就找不到可以分發的servlet了)。

      再來看分發器使用的xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"   
       xmlns:aop="http://www.springframework.org/schema/aop"   
       xmlns:context="http://www.springframework.org/schema/context"  
       xmlns:mvc="http://www.springframework.org/schema/mvc"   
       xmlns:tx="http://www.springframework.org/schema/tx"   
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xsi:schemaLocation="http://www.springframework.org/schema/aop   
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd   
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-3.0.xsd   
        http://www.springframework.org/schema/mvc   
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd   
        http://www.springframework.org/schema/tx   
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">  
      
    <mvc:annotation-driven />  
    <!-- <mvc:default-servlet-handler/> -->
    <context:component-scan base-package="controller" />  
      
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/views/" />  
        <property name="suffix" value=".jsp" /> 
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> 
    </bean>  
</beans>  

          首先,mvc:annotation-driven是一種簡寫模式,表示自動載入DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,是spring MVC為@Controllers分發請求所必須的。context:component-scan是spring中的自動掃描機制,負責掃描包以下所有類中包含的所有spring註解。

然後,就是註冊一個bean了:InternalResourceViewResolver,視圖解析類,就是將servlet中的返回解析到prefix對應參數文件夾下的suffix對應的尾碼文件。

       他需要配合控制類使用:

package controller;


import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.cainiaojava.beans.User;


/**  
* DispatcherController:
* @author xuejupo  [email protected] 
* 
* create in 2016-3-1 下午3:35:13  
*    
*/
@Controller
@RequestMapping("demo")
public class DispatcherController {
    @RequestMapping(method=RequestMethod.GET)    
    public String printWelcome(ModelMap model) {  
        User user = new User();
        user.setInfo("哈哈,我是唯一的用戶!");
        user.setUserName("我是老大!");
        user.setPasswd("不告訴你!");
        model.addAttribute("str0121", "我去,成功了呀!!!"); 
        model.addAttribute("info","當前用戶信息為:");
        model.addAttribute("user", user);
        System.out.println("index.jsp");
        return "index";
    }  
}

@Controller表示這是一個控制器,@RequestMapping("demo")表示他接收尾碼為demo的url(比如http://localhost:8080/test/demo),@RequestMapping(method=RequestMethod.GET)表示請求方式是get的話進這個方法,ModelMap是spring內置的ui控制類,可以將值傳到前端。 return "index",和前邊說的suffix參數的值,合組成index.jsp,所以這個servlet會將請求返回到頁面index.jsp中。

    總結一下:

     首先載入web.xml,web.xml中首先載入context-param,他們沒什麼實際意義,只是一個上下文。然後載入監聽,上面的web.xml配置了log監聽器,所以載入Log4jConfigListener文件(配置log監聽器,應該要在context-param中配置log4jConfigLocation參數,我是犯懶,還沒配日誌。。),然後,載入字元過濾器CharacterEncodingFilter,再然後自上而下載入servlet(本文只有一個servlet,不存在先後順序問題),載入DispatcherServlet分發器,這時候就要載入分發器的配置文件dispatcher_cainiao.xml了。在dispatcher_cainiao.xml中,因為 寫了mvc:annotation-driven,所以載入DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter兩個bean,然後掃描包controller,處理包controller下的所有文件包含的註解,然後配置視圖解析類InternalResourceViewResolver,再然後web項目啟動完畢。

       當我們請求http://localhost:8080/test/demo的時候,首先根據http://localhost:8080/test找到這個項目,然後根據/demo,在servlet-mapping中的url-pattern中查找對應的項,找到一個dispatcher_cainiao,然後根據註解@RequestMapping("demo")找到文件DispatcherController,然後進入相應的方法處理,最後返回的時候根據return值index和配置文件中的InternalResourceViewResolver視圖管理,找到jsp文件/views/index.jsp,最後就是渲染jsp文件了。

      ps:

       首先,web項目的唯一入口是web.xml(不知道是不是有其他入口,我是菜鳥,如果有其他入口希望大神留言指正),其他的xml文件都是在web.xml文件中註冊過的,或者是在servlet或者監聽器中被載入的,而監聽也是在web.xml中註冊的,所以所有的配置文件,都能從web.xml通過一定的路徑走到。學spring框架一定要知道他的大概流程是什麼。所以初學spring,建議找一張白紙,好好畫一畫他的流程走向是什麼,很有幫助的。

     歡迎轉載,但請標明出處:http://www.cnblogs.com/xuejupo/p/5252009.html,  也歡迎跟我討論。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • SEVERE: The required Server component failed to start so Tomcat is unable to start. org.apache.catalina.LifecycleException: Failed to start component
  • 觀察者模式介紹 觀察者模式是一種非常有用的設計模式,在軟體系統中,當一個對象的行為依賴於另一個對象的狀態時,觀察者模式就非常有用。如果不適用觀察者模式,而實現類似的功能,可能就需要另外啟動一個線程不停地監聽另一個對象的狀態,這樣會得不償失。如果在一個複雜的系統中,可能就需要開啟很多的線程來監聽對象狀
  • String類的三個內建正則表達式工具: 1.matches()方法 示例:檢查一個句子是否以大寫字母開頭,以句號結尾 1 public static boolean checkFormat(String sentence){ 2 return sentence.matches("^[A-Z].+\
  • 本章主要是講解讀者在進行FPGA邏輯設計之前的準備工作,需要下載Quartus II軟體和 Modelsim 軟體,一個是用來進行FPGA邏輯設計,一個是用來對邏輯進行理論分析與驗證。 1.1 quartus 軟體安裝 現在Quartus II軟體已經更新到了15.0版本,這個最新版本的一些特性如下
  • 1. 用“==”比較兩個變數,如果兩個變數是基本類型變數,且都是數值類,則值相等就返回true 如果兩個變數是引用型變數,則兩個對象的地址一樣,即指向同一個對象,則返回true 2.equals:String類對equals進行了重寫:1)若是同一個對象,返回true; 2)若不是,則比較它們的值,
  • 平常閱讀源碼什麼的沒有目的性,所以很少去看什麼源碼,主要是比較繞看起來吃力,所以一般工作只是找個模版模仿一下。 以上廢話,割———————————————————————————————————————————————————————————— 最近照常模仿使用了其它項目里的DataSource用法
  • 一、自動化類型轉換:在某種條件下,系統自動完成類型轉換也稱為隱含轉換 ① 兩種類型相容 ② 目標類型大於源類型 ③ 對於表達式,如果一個操作數為double型,則整個表達式可提升為double型 ④ 示例:int i=10;double d=i; 1 public class DataDemo2 2
  • 本文翻譯自《effective modern C++》,由於水平有限,故無法保證翻譯完全正確,歡迎指出錯誤。謝謝! 古人曾說事情的真相會讓你覺得很自在,但是在適當的情況下,一個良好的謊言同樣能解放你。這個Item就是這樣一個謊言。但是,因為我們在和軟體打交道,所以讓我們避開“謊言”這個詞,換句話來說
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...