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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...