1. Spring Spring框架是一個輕量級的解決方案,是一個潛在的一站式商店,用於構建企業就緒的應用程式。Spring框架是一個Java平臺,為開發Java應用程式提供全面的基礎架構支持。Spring處理基礎結構,因此您可以專註於應用程式。Spring使您能夠從“普通的Java對象”(POJO ...
1. Spring
Spring框架是一個輕量級的解決方案,是一個潛在的一站式商店,用於構建企業就緒的應用程式。Spring框架是一個Java平臺,為開發Java應用程式提供全面的基礎架構支持。Spring處理基礎結構,因此您可以專註於應用程式。Spring使您能夠從“普通的Java對象”(POJO)構建應用程式,並將企業服務非侵入性地應用於POJO。此功能適用於Java SE編程模型以及全部和部分Java EE。但是,Spring是模塊化的,允許您僅使用所需的那些部分,而不必引入其餘部分。您可以將IoC容器與頂部的任何Web框架一起使用,但也可以僅使用 Hibernate集成代碼或JDBC抽象層。Spring框架支持聲明式事務管理,通過RMI或Web服務對邏輯的遠程訪問以及用於持久化數據的各種選項。它提供了功能全面的MVC框架,並使您能夠將AOP透明地集成到軟體中。Spring被設計為非侵入式的,這意味著您的域邏輯代碼通常不依賴於框架本身。在您的集成層(例如數據訪問層)中,將存在對數據訪問技術和Spring庫的某些依賴關係。但是,將這些依賴項與其餘代碼庫隔離起來應該很容易。Spring的兩大核心特征:IoC(控制反轉),AOP(面向切麵編程)。IoC作用:把對象的控制權交給容器管理。AOP作用:面向切麵編程(比如日誌列印),底層使用動態代理實現。Spring框架包含組織為約20個模塊的功能。這些模塊分為核心容器,數據訪問/集成,Web,AOP(面向方面的編程),檢測,消息傳遞和測試。Spring的整個完整框 架來說,其設計原則則是"對擴展開放,對修改閉合"(OOP設計原則)。當然Spring還有很多強大的功能,這裡先簡單介紹一下,點到為止。
2. Spring MVC
Spring MVC是基於Servlet API構建的原始web框架,從一開始就已經包含在就包含在Spring框架中,與Spring框架無縫對接。全稱應該為Spring Web MVC,其來源於模塊spring-webmvc。但是,通常我們叫它Spring MVC(習慣)。Spring MVC框架是圍繞一個 DispatcherServlet (核心控制器)來設計的,這個 Servlet會把請求分發給各個處理器,並支持可配置的處理器映射、視圖渲染、本地化、時區 與主題渲染等,甚至還能支持文件上傳。"對擴展開放"是Spring Web MVC框架一個重要的設計原則。Spring Web MVC核心類庫中的一些方法被定義為 final 方法。Sp'ring MVC的數據綁定非常靈活方便,視圖解析也設計的非常靈活與方便,並且提供了好多功能強大的註解機制。當然,Spring MVC的強大之處不是一兩句話可以搞定的,我們應該參考其文檔,並且深入學習鑽研,最好研究研究源碼。這裡話不多說,點到為止。
3. Spring MVC處理(jQuery)Ajax請求(前臺不發送數據,後臺返回普通字元串)
開發環境:Eclipse+Tomcat+Spring MVC+Jackson+JSP+jQuery+Ajax
本篇博客比較長,原本是一個小的demo,寫這麼長不值,不,我認為值,因為我感覺自己寫的還可以(哈哈!裝一波),這些都是筆者一字一句寫的,當然有參考一些東西(本人最討厭複製粘貼),加上自己的理解,涉及到代碼完全認真實踐過,自己從頭到尾寫一遍,也是對自己知識的積累以及經驗的提升,Spring MVC文檔和Spring文檔等,請大家認真看下去,看完這篇,你不僅掌握了Ajax,認識了Spring的好處,還會熟知Spring MVC的執行流程,還會接觸到有趣的日誌列印。當然也可以免費獲取jar包(有源碼鏈接),百度都有(基本都免費)。所以普通的一些jar包都是免費的,沒有必要花一些代價去活得開發包。本質來說,框架只是個模板,我們遵從框架的規範來開發就行了,畢竟使用一些框架是我們的開發變得簡單高效,筆者認為還是應該瞭解一下底層核心的原理比較好,這樣便於在我們開發的時候遇到bug的時候可以迅速做出決策和解決。寫博客,我是認真的。
(1)搭建環境
Eclipse中新建Java Web項目,並把項目部署到Tomcat容器中。下麵是項目的結構:
項目基本結構很簡單,沒啥可說的。這裡說一下lib裡面的jar包。既然我們想使用Spring MVC進行開發,必須導入其開發包。上面說了,Spring MVC其實是集成在Spring中的,所以也是導入Spring開發包。本次使用spring-framework-4.0.0.RELEASE開發包。
Spring開發包:spring-aop面向切麵編程所用到的包。spring-aspects提供對AspectJ(面向切麵的一個框架)的支持,spring-beans包含訪問配置文件,創建和管理Bean以及進行控制反轉和依賴註入操作相關的所有類。spring-core是Spring的核心包(核心工具類)。spring-expression是Spring的表達式語言,spring-jdbc它包含了spring 與 JDBC 數據訪問時進行封裝的所有類,提供使用springjdbc的最佳實現(利用jdbc template)。spring-orm是Spring對DAO特性進行擴展,支持一些ORM(對象關係映射)框架(比如MyBatis和Hibernate等)。spring-test提供了對Junit等測試框架的簡單封裝,這讓我們在對Spring的代碼進行測試時更加方便和快捷。spring-tx包為JDBC、Hibernate、JDO、JPA等提供了一致的聲明式的編程式事物管理。spring-web包含web應用研發時用到Spring框架時所需要的的核心類。spring-webmvc包含了Spring webmvc框架相關的所有類。
log4j日誌信息包。不導這個包的話會報錯。
Jasckson三個包(前幾篇博客說過好多遍)。這裡導入Jackson包的原因說一下。1. Spring MVC內置的json與對象轉換器依賴於Jackson類庫。(底層通過對Jackson的一些方法進行封裝實現)。2. 簡單好用我感覺,效率也還可以。當然也可以實現自己的json與對象的轉換器(題外話)。
com.springsource三個jar包,主要是為了提供Spring對Apache的一些服務的支持。Tomcat就是Apache的,不導這3個包的話會報錯。當然,這裡只是導入了spring的一部分常用的包,還有其他的(自己百度下spring開發包,在裡面找找),本次開發也沒把這些spring包全部用到,主要是為了著重介紹一下。好了,jar包說完了。下麵進行開發。這裡不使用任何註解的目的說一下,只是基於XML配置實現。其實我們使用註解會簡單方便很多(後面會有更新的),此篇文章主要是為了便於大家熟悉Spring MVC的執行流程,並使用它最最原始的一些配置以及方法。方便大家瞭解更深層次的東西,以及深入瞭解Spring MVC一些核心的東西。因為我們天天使用註解,但是估計我們都沒瞭解過註解的機制以及原理,註解有什麼用。以及註解代替了那些我們之前開發比較繁雜的操作以及方法。有時候我們研究一些東西,不能只停留在錶面會使用就行了,我們深入到底層的話會有意想不到的收穫及理解。
(2)編寫jsp文件
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE html> <html> <head> <base href="<%=basePath%>"> <title>I LOVE YOU</title> <link rel="stylesheet" type="text/css" href=""> <script type="text/javascript" src="index.js"></script> <script type="text/javascript" src="jquery-3.2.1.min.js"></script> </head> <body> <button id="mybutton1" value="springmvc處理ajax請求" onclick="fun1()" >(jquery)ajax請求(不發送數據)</button> <spand id="show1" /> <br/> <hr/> </body>
很簡單,定義了一個按鈕。並調用js文件相關的函數進行處理,<span>標簽是為了顯示內容。頁面引入自定義的js文件和jQeury的js文件(註意名稱和路徑)。
(3)編寫js文件
/** * */ //使用jquery提交ajax請求(不攜帶數據) function fun1(){ $.ajax({ type:"POST", //發送方式 url:"UserController1", //請求地址 data:"", //數據為空 success:function(data){ //成功後的回調函數 $("#show1").html(data); //頁面展示內容 } }); }
很簡單,就寫了一個fun1()函數。用來響應按鈕。雖然說,討論客戶端不發送數據沒多大意義,這裡我們還是討論一下吧。在學習java基礎的時候,我們還經常討論"空"呢。不是嗎?這裡主要是為了熟悉一下代碼執行的流程,畢竟我們學習的過程是由淺入深的。閑話少敘。
(4)編寫controller類
package com.controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.HttpRequestHandler; public class UserController1 implements HttpRequestHandler{ @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setCharacterEncoding("UTF-8"); String str = "我是一個 springmvc"; try { response.getWriter().print(str); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
這裡定義了一個controller類,並且實現了HttpRequestHandler介面,並實現介面中的抽象方法。方法中定義了一個字元串,利用response獲取列印流進行輸出即可。Spring MVC中。一般在我們編寫controller(也就是一個handler,用來處理客戶端的請求),要能被Sping MVC識別它是一個controller類,因為這裡沒有用到註解。所以我們有2種方法。
第一種:編寫controller類,實現org.springframework.web.servlet.mvc.Controller介面,然後交給核心控制器調用相對應的處理器適配器進行處理。不過,實現了Controller,就必須實現其中的抽象方法public abstract ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)。這個方法必須返回一個ModelAndView對象,而我們所作的是對字元串數據和json數據的處理。所以在這裡我們並沒有選擇實現Controller介面。
第二種:編寫controller類,實現org.springframework.web.HttpRequestHandler介面,然後交給核心控制器調用相應的處理器適配器進行處理,並實現其中的抽象方法。自己可以百度一下Spring MVC的執行流程,這裡不多說。
public abstract void handleRequest(HttpServletRequest request, HttpServletResponse response) 我們註意到,這個方法是沒有返回值的,所以就方便了我們對字元串數據和json數據的處理。註意到有2個參數request和response(這是Servlet的東西)。Spring MVC支持的支持的參數類型:
HttpServletRequest 對象,HttpServletResponse 對象,HttpSession 對象,Model/ModelMap 對象。這裡我們用到了其中的2個。
(5)配置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"> <display-name>MySpringMVCAjax</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 配置springmvc核心控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 對靜態資源進行放行 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/static/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <!-- 配置編碼過濾器 --> <filter> <filter-name>SpringCharacterEncodingFilter</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>SpringCharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
這裡我們配置了三個東西。
第一個,配置Spring核心控制器。Sping MVC核心控制器(前端控制器或中央處理器)org.springframework.web.servlet.DispatcherServlet,DispatcherServlet 其實就是個 Servlet (它繼承自 HttpServlet 基類),同樣也需要在你 web應用的 web.xml 配置文件下聲明。你需要在 web.xml 文件中把你希望 DispatcherServlet 處理的請求映射到對應的URL上去。這就是標準的Java EE Servlet配 置。DispatcherServlet就是一個Sping MVC處理請求的一個中央處理器,負責調度處理器映射器,處理器適配器以及視圖解析器。配置初始化參數來載入Sping MVC的主配置文件springmvc.xml,這裡我們把它放在src目錄下。
第二個,給靜態資源放行。這裡註意一下。我們在核心控制器<url-pattern>標簽下配置的是 / ,表示所有訪問的url都交給核心控制器去處理,這樣導致有可能載入不到靜態資源文件(js,css,img)。解決辦法:
第一種:在springmvc.xml文件中配置<mvc:default-servlet-handler /><!-- 表示對所有靜態資源進行放行 -->(比較高級的方法)
第二種:對靜態資源進行放行,如我們web.xml所示。當然,也可以在spring.xml文件進行放行,語法為:
<resources location="/js/" mapping="/js/**" />
<resources location="/css/" mapping="/css/**" />
<resources location="/images/" mapping="/images/**" />
這裡使用web.xml對靜態資源進行放行,主要是因為這個方法簡單易懂。後面我會對博客內容進行更新升級,再採取比較高級的方法。
第三種:配置核心控制器時,把<url-pattern>標簽設置為 *.do 或者 .action就好了。表示以.do結尾的或者以.action結尾的URL都由前端控制器DispatcherServlet來解析。這種方法也可以,但是到時訪問路徑的時候要加上這個尾碼,看起來不太舒服(有一點強迫症的人應該懂)。當然筆者估計沒有吧。筆者只是採取一些簡單說不上高效的方法。
第三個,就是配置spring提供編碼過濾器。web.xml配置的編碼過濾器為了防止前端傳入的中文數據出現亂碼問題,使用Spring提供的編碼過濾器來統一編碼。配置為UTF-8。當然也可以使用GBK等其他編碼。GBK編碼方式的編碼是以中國國情而創造的,在國際上的相容性不好,這也是為什麼大多數的網頁是使用UTF-8編碼而不是GBK。UTF-8好處:相容ASCII,存儲英文文件都是單位元組,文件小。在eclipse中把項目的編碼也設置為UTF-8,JSP頁面中字元編碼也設置為UTF-8。瀏覽器網頁字元編碼也設置為UTF-8。反正就是統統UTF-8的樣子。做這麼多主要是統一編碼,解決中文亂碼亂碼問題。因為以前使用servlet和struts2的時候,經常出現中文亂碼問題,讓人摸不著什麼頭腦。所以。Spring提供的這個編碼過濾器就比較方便好用了。所以說Spring是一個神奇的東西。我們研讀一下Spring源碼,看看Spring開發的文檔,就可以汲取一些精華(精髓)。Spring提供的編碼過濾器,org.springframework.web.filter.CharacterEncodingFilter類,註意把路徑寫正確。初始化參數(也就是編碼)encoding為UTF-8。Spring里的字元過濾器CharacterEncodingFilter是針對請求的,forceEncoding=true是意思是指無論客戶端請求是否包含了編碼,都用過濾器里的編碼來解析請求。forceEncoding預設為false。forceEncoding為true效果: request.setCharacterEncoding("UTF-8");forceEncoding為false的效果:
request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8")。 <url-pattern>標簽配置的/*代表過濾所有請求,從而將編碼設置為UTF-8。好了。web.xml到此結束。其實有時候我們只是開發一個簡單的小例子demo,看起來很簡單。但是我們要瞭解底層到底是怎麼實現的。比如Java的底層,JVM(Java虛擬機)用c/c++編寫,Java類庫用Java語言編寫。還有比如native本地方法,其底層本質也是c/c++編寫的,Java只是調用了它的介面。這也就解釋了為什麼native方法效率一般比較高。那麼問題來了,c語言用什麼編寫的 ? 這個可以自行谷歌或百度,這裡不多說。當然,一個項目或者工作的執行流程我們也必須熟知。這次開發看起來很簡單,但是我們把涉及到的知識內容都會為大家詳細講解,並且都是本人一字一句經過推敲實踐進行編寫的。當然,本人也是菜鳥一枚。知識有限。但是我們可以經過學習來獲取更多的知識,提升自己的能力,從而達到人生的巔峰。不多說了(跑題了,哈哈!)。
(6)配置springmvc.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" 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"> <!-- 配置user實體類 --> <bean id="user" class="com.pojo.User" /> <!-- 配置handler--> <bean name="/UserController1" class="com.controller.UserController1" /> <bean name="/UserController2" class="com.controller.UserController2" /> <bean name="/UserController3" class="com.controller.UserController3" /> <!-- 配置處理器映射器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!-- 配置處理器適配器 --> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/> <!-- 配置json與對象的轉換器 --> <bean id="myconverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
springmvc.xml是本次開發的主配置文件。通過觀察得知,頂層標簽<beans>包含了許多bean模塊。Spring Bean其實就是是被實例的,組裝的及被Spring 容器管理的Java對象。一個bean相當於一個實體類對象,通過IoC(控制反轉,也叫依賴註入)我們可以把bean註入到容器當中,交給Spring容器管理(比如bean的實例化)。這樣做的目的其實解耦合。因為軟體設計的原則就是高內聚,低耦合。Spring預設的bean實例是單例的,我們可以用scope屬性來設置bean的作用域。scope可以接受Singleton(單例模式,每次獲取bean只有一個實例)、prototype(原型模式,每次獲取bean都會產生新的實例)、request(每次HTTP request請求都會產生不同的Bean實例)、session(每次HTTP session請求都會產生不同的Bean實例)、global session (每個全局的HTTPSession對應一個Bean實例。僅在portlet Context的時候才有效。)5個值。我們常用單例模式,因為創建對象本身代價比較高,耗費資源,單例的本身也滿足我們的需求了。當然我們也可以根據不同的需求設置不同的scope,這本無可厚非。還有,註意一下引入的xsd文件,Spring文件中的引用的xsd文件是用於校驗xml文件的格式用的。Spring預設在啟動時是要載入XSD文件來驗證xml文件的。相當於是約束文件。這裡我們引入了三個xsd文件,spring-beans-xsd包含對bean的解釋。sprng-mvc.xsd包含了對<mvc>等標簽的解釋,spring-context.xsd包含對context的解釋,這裡我們其實只用到了spring-beans.xsd約束文件。
我們具體看一下配置了什麼東西。
1. 把User實體類註入到容器(下麵會貼User類的代碼,這裡暫時還沒用到)。相當於是通過<bean>標簽來裝配一個User類,我們就可以通過獲取bean來達到獲取User實體對象的目的。設置bean的id(一個bean的唯一標識)和class(類的全包路徑 包.類)。
2. 配置controller(也就是handler,處理客戶端請求)。這裡我們配置了好三個controller。我們看UserController1(對應上面的方法UserController1)的配置,配置了一個name和class。Spring MVC要識別請求的url,就是通過調用處理器映射器獲取到這個name的名稱,找到controller類,然後交給處理器設配器去處理controller。相當於就是映射路徑。註意名稱前要加上/ 不然無法識別。這裡我們設置name=”/UserController1“和類名保持一致(為了方便),當然也可以起其他名字,別忘了/,前臺提交的url和此處name的名稱要保持一致。class為UserController1的全包類路徑。
3. 配置處理器映射器BeanNameUrlHandlerMapping。不需要指定id,只配置全類路徑即可,即class。這個處理器映射器,將bean的name作為url進行查找,需要在配置Handler時指定bean的 name(url)。
查看spring-webmvc包下麵的DispatcherServlet.properties 資源文件:
# Default implementation classes for DispatcherServlet's strategy interfaces. # Used as fallback when no matching beans are found in the DispatcherServlet context. # Not meant to be customized by application developers. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\ org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\ org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\ org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
Spring MVC的處理器映射器,常用的有2個,一個是org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,繼承了
AbstractDetectingUrlHandlerMapping抽象類,它又向上繼承了AbstractUrlHandlerMapping抽象類,它又向上繼承了AbstractHandlerMapping,
AbstractHandlerMapping抽象類實現了HandlerMapping介面。
另一個是org.springframework.web.servlet.handler.SimpleUrlHandlerMapping,繼承了AbstractUrlHandlerMapping抽象類,
AbstractUrlHandlerMapping繼承了AbstractHandlerMapping抽象類,AbstractHandlerMapping實現了org.springframework.web.servlet.HandlerMapping
介面。觀察資源文件發現,BeanNameUrlHandlerMapping是Spring MVC的預設處理器映射器,這裡我們就使用這個。若要使用SimpleUrlHandlerMapping,
我們根據它的語法來就行了。可以這樣配置:
bean id="UserController1" class="com.controller.UserController1" /> <!-- 簡單URL配置處理器映射器 --> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/UserController1">UserController1</prop> </props> </property> </bean>
當然這兩種處理器映射器配置可以並存,核心控制器會正確的去判斷 url 用哪個 Handler 去處理。
註意這個上面資源文件的處理器映射器DefaultAnnotationHandlerMapping,通過查看源碼,它已經被廢棄了。被拋棄的感覺不好受啊。
(估計DefaultAnnotationHandlerMapping的內心是崩潰的)。
4. 配置處理器適配器。不需要指定id,class為全類路徑。核心控制器調用處理器映射器找到了Controller類,那麼誰來處理這個Controller呢。那麼此時處理器適配器就閃亮登場了。什麼是處理器適配器呢。且聽下回分解,本章完。。。(皮一下)。通過觀察以上資源文件。我們發現。Spring MVC的處理器適配器,常用的有2個。
一個是org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,一個是org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
這2個類都實現了HandlerAdapter介面。SimpleControllerHandlerAdapter處理的Handler必須實現Conreoller介面,一般返回一個ModelAndView對象。
HttpRequestHandlerAdapter處理的Handler必須實現HttpRequestHandler介面,一般用來處理字元串或者json數據。因為其抽象方法沒有返回值。AnnotationMethodHandlerAdapter已經廢棄了,不多說。當然兩種適配器可以共存,配置不同的映射器找到不同的controller。
Spring MVC預設的處理器適配器是HttpRequestHandlerAdapter 。
5. 配置視圖解析器。不需要指定id,class為全類路徑。我們這裡用的是InternalResourceViewResolver,配置它的class路徑,註意有2個屬性。prefix表示返回視圖頁面的首碼,suffix表示返回視圖頁面的尾碼。比如一般我們要視圖解析完成後返回一個頁面index.jsp時,prefix相當於配置的是其根目錄(在哪兒),suffix就是.jsp,這樣在我們使用註解進行開發的時候,只需要返回一個字元串"index"就行了。上面那樣配置,表示在 Handler 中只需要返回在 WebContent根目錄下的jsp 文件名就ok了(為了簡單方便,開發比較高效)。視圖解析器作用它負責將一個代表邏輯視圖名的字元串 (String)映射到實際的視圖類型 View 上。通過以上資源文件發現。註意HandlerExceptionResolver處理器異常解析器。它負責將捕獲的異常映射到不同的視 圖上去,此外還支持更複雜的異常處理代碼。Spring MVC的視圖解析器這裡介紹3種:
第一種:使用ViewResolver介面解析視圖
org.springframework.web.servlet.view.InternalResourceViewResolver類,通過連續向上繼承,實現org.springframework.web.servlet.ViewResolver介面。在實際應用中InternalResourceViewResolver也是使用的最廣泛的一個視圖解析器。本次開發就用的是這個視圖解析器。這個比較常用。InternalResourceViewResolver解析器可以解釋為內部資源視圖解析器。InternalResourceViewResolver會把返回的視圖名稱都解析為InternalResourceView對象,InternalResourceView會把Controller處理器方法返回的模型屬性都存放到對應的request屬性中,然後通過RequestDispatcher在伺服器端把請求forword重定向到目標URL。
介面中的方法:通過傳來的參數解析視圖,並返回一個View對象。註意Handler類實現Conteoller介面方法時,就返回了一個ModelAndView對象。ModelAndView 是SpringMVC 框架的一個底層對象,包括 Model 和 View。
public abstract interface ViewResolver
{
public abstract View resolveViewName(String paramString, Locale paramLocale)
throws Exception;
}
第二種:使用RequestToViewNameTranslator介面解析視圖。DefaultRequestToViewNameTranslator為這個介面的實現子類。
這個介面定義了一個抽象方法
public abstract interface RequestToViewNameTranslator
{
public abstract String getViewName(HttpServletRequest paramHttpServletRequest)
throws Exception;
}
表示根據request請求返回一個視圖名稱的字元串。
第三種:使用FlashMapManager介面解析視圖。SessionFlashMapManager為這個介面的實現子類。
FlashMap管理器。它能夠存儲並取回兩次請求之間 的 FlashMap 對象。後者可用於在請求之間傳遞數據,通常 是在請求重定向的情境下使用。
這個介面定義的方法:自己看看就好了,在這裡不做過多介紹。
public abstract interface FlashMapManager
{
public abstract FlashMap retrieveAndUpdate(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse);
public abstract void saveOutputFlashMap(FlashMap paramFlashMap, HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse);
}
Map肯定時用來保存數據的。RedirectView在頁面跳轉,數據的保存依賴於FlashMap和FlashMapManger,FlashMapManger在容器初始化時被填入,而FlashMap從Manger可以獲取。
5. 配置json與對象的轉換器。這裡暫時用不到。下麵會解釋。先跳過。其實Spring MVC內置的json與對象的轉換器底層還是用Jasckson類庫實現。
(7)配置log4j.properties日誌文件
### set log levels ### log4j.rootLogger = INFO , console , D ### console ### log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] %m%n ### log file ### log4j.appender.D = org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File =../logs/IvaDubboWeb-info.log log4j.appender.D.Append = true log4j.appender.D.Threshold = INFO log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n ### out zhiding log file ### log4j.logger.haha = INFO, haha log4j.additivity.haha = false log4j.appender.haha = org.apache.log4j.DailyRollingFileAppender log4j.appender.haha.File =D:/logs/mylog.log log4j.appender.haha.Append = true log4j.appender.haha.Threshold = INFO log4j.appender.haha.layout = org.apache.log4j.PatternLayout log4j.appender.haha.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n
Log4j簡單介紹:
Log4j是Apache的一個開源項目,通過使用Log4j,我們可以控制日誌信息輸送的目的地是控制台、文件、GUI組件,甚至是套介面伺服器、NT的事件記錄器、UNIX Syslog守護線程等;我們也可以控制每一條日誌的輸出格式;通過定義每一條日誌信息的級別,我們能夠更加細緻地控制日誌的生成過程。Log4j有三個主要的組件:Loggers(記錄器),Appenders (輸出源)和Layouts(佈局)。這裡可簡單理解為日誌類別,日誌要輸出的地方和日誌以何種形式輸出。綜合使用這三個組件可以輕鬆地記錄信息的類型和級別,並可以在運行時控制日誌輸出的樣式和位置。
1. 配置根logger,日誌輸出級別為INFO級別。log4j的輸出級別:TRACE < DEBUG < INFO < WARN < ERROR < FATAL。比INFO級別高的也會列印輸出,比INFO低的不會輸出。
2. 配置console,在eclipse的控制台列印日誌信息。
3. 配置輸出到文件。一個是輸出到一般性文件中,另一個是輸出到我們指定的文件中。很簡單。(筆者對log4j還琢磨了半天,主要是瞭解日誌列印到底是什麼玩意兒)。
對上面log4j簡單測試一下(註意要導入log4j開發包和單元測試JUinit包,並把log4j.properties文件放在src目錄下)。列印到控制台:
package com.log4j; import org.apache.log4j.Logger; import org.junit.Test; public class Log4jTest { @Test public void test() { // BasicConfigurator.configure(); //自動快速地使用預設Log4j環境。 Logger logger = Logger.getLogger(Log4jTest.class); logger.info("log4j"); logger.info("是"); logger.error("什麼"); logger.debug("呢"); } }
運行效果:debug級別比INFO低,無輸出。
列印日誌到指定文件:把方法放在一個類中就行了
@Test public void test1() { // BasicConfigurator.configure(); //自動快速地使用預設Log4j環境。 Logger logger = Logger.getLogger("haha"); logger.info("我"); logger.info("要"); logger.info("學");