欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Spring 的優(yōu)秀工具類(lèi)盤(pán)點(diǎn),第 1 部分: 文件資源操作和 Web 相關(guān)工具類(lèi)
Spring 不但提供了一個(gè)功能全面的應用開(kāi)發(fā)框架,本身還擁有眾多可以在程序編寫(xiě)時(shí)直接使用的工具類(lèi),您不但可以在 Spring 應用中使用這些工具類(lèi),也可以在其它的應用中使用,這些工具類(lèi)中的大部分是可以在脫離 Spring 框架時(shí)使用的。了解 Spring 中有哪些好用的工具類(lèi)并在程序編寫(xiě)時(shí)適當使用,將有助于提高開(kāi)發(fā)效率、增強代碼質(zhì)量。在這個(gè)分為兩部分的文章中,我們將從眾多的 Spring 工具類(lèi)中遴選出那些好用的工具類(lèi)介紹給大家。第 1 部分將介紹與文件資源操作和 Web 相關(guān)的工具類(lèi)。

文件資源操作

文件資源的操作是應用程序中常見(jiàn)的功能,如當上傳一個(gè)文件后將其保存在特定目錄下,從指定地址加載一個(gè)配置文件等等。我們一般使用 JDK 的 I/O 處理類(lèi)完成這些操作,但對于一般的應用程序來(lái)說(shuō),JDK 的這些操作類(lèi)所提供的方法過(guò)于底層,直接使用它們進(jìn)行文件操作不但程序編寫(xiě)復雜而且容易產(chǎn)生錯誤。相比于 JDK 的 File,Spring 的 Resource 接口(資源概念的描述接口)抽象層面更高且涵蓋面更廣,Spring 提供了許多方便易用的資源操作工具類(lèi),它們大大降低資源操作的復雜度,同時(shí)具有更強的普適性。這些工具類(lèi)不依賴(lài)于 Spring 容器,這意味著(zhù)您可以在程序中象一般普通類(lèi)一樣使用它們。

加載文件資源

Spring 定義了一個(gè) org.springframework.core.io.Resource 接口,Resource 接口是為了統一各種類(lèi)型不同的資源而定義的,Spring 提供了若干 Resource 接口的實(shí)現類(lèi),這些實(shí)現類(lèi)可以輕松地加載不同類(lèi)型的底層資源,并提供了獲取文件名、URL 地址以及資源內容的操作方法。

訪(fǎng)問(wèn)文件資源

假設有一個(gè)文件地位于 Web 應用的類(lèi)路徑下,您可以通過(guò)以下方式對這個(gè)文件資源進(jìn)行訪(fǎng)問(wèn):

  • 通過(guò) FileSystemResource 以文件系統絕對路徑的方式進(jìn)行訪(fǎng)問(wèn);
  • 通過(guò) ClassPathResource 以類(lèi)路徑的方式進(jìn)行訪(fǎng)問(wèn);
  • 通過(guò) ServletContextResource 以相對于Web應用根目錄的方式進(jìn)行訪(fǎng)問(wèn)。

相比于通過(guò) JDK 的 File 類(lèi)訪(fǎng)問(wèn)文件資源的方式,Spring 的 Resource 實(shí)現類(lèi)無(wú)疑提供了更加靈活的操作方式,您可以根據情況選擇適合的 Resource 實(shí)現類(lèi)訪(fǎng)問(wèn)資源。下面,我們分別通過(guò) FileSystemResource 和 ClassPathResource 訪(fǎng)問(wèn)同一個(gè)文件資源:


清單 1. FileSourceExample
package com.baobaotao.io;                        import java.io.IOException;                        import java.io.InputStream;                        import org.springframework.core.io.ClassPathResource;                        import org.springframework.core.io.FileSystemResource;                        import org.springframework.core.io.Resource;                        public class FileSourceExample {                        public static void main(String[] args) {                        try {                        String filePath =                        "D:/masterSpring/chapter23/webapp/WEB-INF/classes/conf/file1.txt";                        // ① 使用系統文件路徑方式加載文件                        Resource res1 = new FileSystemResource(filePath);                        // ② 使用類(lèi)路徑方式加載文件                        Resource res2 = new ClassPathResource("conf/file1.txt");                        InputStream ins1 = res1.getInputStream();                        InputStream ins2 = res2.getInputStream();                        System.out.println("res1:"+res1.getFilename());                        System.out.println("res2:"+res2.getFilename());                        } catch (IOException e) {                        e.printStackTrace();                        }                        }                        }                        

在獲取資源后,您就可以通過(guò) Resource 接口定義的多個(gè)方法訪(fǎng)問(wèn)文件的數據和其它的信息:如您可以通過(guò) getFileName() 獲取文件名,通過(guò) getFile() 獲取資源對應的 File 對象,通過(guò) getInputStream() 直接獲取文件的輸入流。此外,您還可以通過(guò) createRelative(String relativePath) 在資源相對地址上創(chuàng )建新的資源。

在 Web 應用中,您還可以通過(guò) ServletContextResource 以相對于 Web 應用根目錄的方式訪(fǎng)問(wèn)文件資源,如下所示:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>                        <jsp:directive.page import="                        org.springframework.web.context.support.ServletContextResource"/>                        <jsp:directive.page import="org.springframework.core.io.Resource"/>                        <%                        // ① 注意文件資源地址以相對于 Web 應用根路徑的方式表示                        Resource res3 = new ServletContextResource(application,                        "/WEB-INF/classes/conf/file1.txt");                        out.print(res3.getFilename());                        %>                        

對于位于遠程服務(wù)器(Web 服務(wù)器或 FTP 服務(wù)器)的文件資源,您則可以方便地通過(guò) UrlResource 進(jìn)行訪(fǎng)問(wèn)。

為了方便訪(fǎng)問(wèn)不同類(lèi)型的資源,您必須使用相應的 Resource 實(shí)現類(lèi),是否可以在不顯式使用 Resource 實(shí)現類(lèi)的情況下,僅根據帶特殊前綴的資源地址直接加載文件資源呢?Spring 提供了一個(gè) ResourceUtils 工具類(lèi),它支持“classpath:”和“file:”的地址前綴,它能夠從指定的地址加載文件資源,請看下面的例子:


清單 2. ResourceUtilsExample
package com.baobaotao.io;                        import java.io.File;                        import org.springframework.util.ResourceUtils;                        public class ResourceUtilsExample {                        public static void main(String[] args) throws Throwable{                        File clsFile = ResourceUtils.getFile("classpath:conf/file1.txt");                        System.out.println(clsFile.isFile());                        String httpFilePath = "file:D:/masterSpring/chapter23/src/conf/file1.txt";                        File httpFile = ResourceUtils.getFile(httpFilePath);                        System.out.println(httpFile.isFile());                        }                        }                        

ResourceUtils 的 getFile(String resourceLocation) 方法支持帶特殊前綴的資源地址,這樣,我們就可以在不和 Resource 實(shí)現類(lèi)打交道的情況下使用 Spring 文件資源加載的功能了。

本地化文件資源

本地化文件資源是一組通過(guò)本地化標識名進(jìn)行特殊命名的文件,Spring 提供的 LocalizedResourceHelper 允許通過(guò)文件資源基名和本地化實(shí)體獲取匹配的本地化文件資源并以 Resource 對象返回。假設在類(lèi)路徑的 i18n 目錄下,擁有一組基名為 message 的本地化文件資源,我們通過(guò)以下實(shí)例演示獲取對應中國大陸和美國的本地化文件資源:


清單 3. LocaleResourceTest
package com.baobaotao.io;                        import java.util.Locale;                        import org.springframework.core.io.Resource;                        import org.springframework.core.io.support.LocalizedResourceHelper;                        public class LocaleResourceTest {                        public static void main(String[] args) {                        LocalizedResourceHelper lrHalper = new LocalizedResourceHelper();                        // ① 獲取對應美國的本地化文件資源                        Resource msg_us = lrHalper.findLocalizedResource("i18n/message", ".properties",                        Locale.US);                        // ② 獲取對應中國大陸的本地化文件資源                        Resource msg_cn = lrHalper.findLocalizedResource("i18n/message", ".properties",                        Locale.CHINA);                        System.out.println("fileName(us):"+msg_us.getFilename());                        System.out.println("fileName(cn):"+msg_cn.getFilename());                        }                        }                        

雖然 JDK 的 java.util.ResourceBundle 類(lèi)也可以通過(guò)相似的方式獲取本地化文件資源,但是其返回的是 ResourceBundle 類(lèi)型的對象。如果您決定統一使用 Spring 的 Resource 接表征文件資源,那么 LocalizedResourceHelper 就是獲取文件資源的非常適合的幫助類(lèi)了。

文件操作

在使用各種 Resource 接口的實(shí)現類(lèi)加載文件資源后,經(jīng)常需要對文件資源進(jìn)行讀取、拷貝、轉存等不同類(lèi)型的操作。您可以通過(guò) Resource 接口所提供了方法完成這些功能,不過(guò)在大多數情況下,通過(guò) Spring 為 Resource 所配備的工具類(lèi)完成文件資源的操作將更加方便。

文件內容拷貝

第一個(gè)我們要認識的是 FileCopyUtils,它提供了許多一步式的靜態(tài)操作方法,能夠將文件內容拷貝到一個(gè)目標 byte[]、String 甚至一個(gè)輸出流或輸出文件中。下面的實(shí)例展示了 FileCopyUtils 具體使用方法:


清單 4. FileCopyUtilsExample
package com.baobaotao.io;                        import java.io.ByteArrayOutputStream;                        import java.io.File;                        import java.io.FileReader;                        import java.io.OutputStream;                        import org.springframework.core.io.ClassPathResource;                        import org.springframework.core.io.Resource;                        import org.springframework.util.FileCopyUtils;                        public class FileCopyUtilsExample {                        public static void main(String[] args) throws Throwable {                        Resource res = new ClassPathResource("conf/file1.txt");                        // ① 將文件內容拷貝到一個(gè) byte[] 中                        byte[] fileData = FileCopyUtils.copyToByteArray(res.getFile());                        // ② 將文件內容拷貝到一個(gè) String 中                        String fileStr = FileCopyUtils.copyToString(new FileReader(res.getFile()));                        // ③ 將文件內容拷貝到另一個(gè)目標文件                        FileCopyUtils.copy(res.getFile(),                        new File(res.getFile().getParent()+ "/file2.txt"));                        // ④ 將文件內容拷貝到一個(gè)輸出流中                        OutputStream os = new ByteArrayOutputStream();                        FileCopyUtils.copy(res.getInputStream(), os);                        }                        }                        

往往我們都通過(guò)直接操作 InputStream 讀取文件的內容,但是流操作的代碼是比較底層的,代碼的面向對象性并不強。通過(guò) FileCopyUtils 讀取和拷貝文件內容易于操作且相當直觀(guān)。如在 ① 處,我們通過(guò) FileCopyUtils 的 copyToByteArray(File in) 方法就可以直接將文件內容讀到一個(gè) byte[] 中;另一個(gè)可用的方法是 copyToByteArray(InputStream in),它將輸入流讀取到一個(gè) byte[] 中。

如果是文本文件,您可能希望將文件內容讀取到 String 中,此時(shí)您可以使用 copyToString(Reader in) 方法,如 ② 所示。使用 FileReader 對 File 進(jìn)行封裝,或使用 InputStreamReader 對 InputStream 進(jìn)行封裝就可以了。

FileCopyUtils 還提供了多個(gè)將文件內容拷貝到各種目標對象中的方法,這些方法包括:

方法 說(shuō)明
static void copy(byte[] in, File out) 將 byte[] 拷貝到一個(gè)文件中
static void copy(byte[] in, OutputStream out) 將 byte[] 拷貝到一個(gè)輸出流中
static int copy(File in, File out) 將文件拷貝到另一個(gè)文件中
static int copy(InputStream in, OutputStream out) 將輸入流拷貝到輸出流中
static int copy(Reader in, Writer out) 將 Reader 讀取的內容拷貝到 Writer 指向目標輸出中
static void copy(String in, Writer out) 將字符串拷貝到一個(gè) Writer 指向的目標中

在實(shí)例中,我們雖然使用 Resource 加載文件資源,但 FileCopyUtils 本身和 Resource 沒(méi)有任何關(guān)系,您完全可以在基于 JDK I/O API 的程序中使用這個(gè)工具類(lèi)。

屬性文件操作

我們知道可以通過(guò) java.util.Properties的load(InputStream inStream) 方法從一個(gè)輸入流中加載屬性資源。Spring 提供的 PropertiesLoaderUtils 允許您直接通過(guò)基于類(lèi)路徑的文件地址加載屬性資源,請看下面的例子:

package com.baobaotao.io;                        import java.util.Properties;                        import org.springframework.core.io.support.PropertiesLoaderUtils;                        public class PropertiesLoaderUtilsExample {                        public static void main(String[] args) throws Throwable {                        // ① jdbc.properties 是位于類(lèi)路徑下的文件                        Properties props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties");                        System.out.println(props.getProperty("jdbc.driverClassName"));                        }                        }                        

一般情況下,應用程序的屬性文件都放置在類(lèi)路徑下,所以 PropertiesLoaderUtils 比之于 Properties#load(InputStream inStream) 方法顯然具有更強的實(shí)用性。此外,PropertiesLoaderUtils 還可以直接從 Resource 對象中加載屬性資源:

方法 說(shuō)明
static Properties loadProperties(Resource resource) 從 Resource 中加載屬性
static void fillProperties(Properties props, Resource resource) 將 Resource 中的屬性數據添加到一個(gè)已經(jīng)存在的 Properties 對象中

特殊編碼的資源

當您使用 Resource 實(shí)現類(lèi)加載文件資源時(shí),它默認采用操作系統的編碼格式。如果文件資源采用了特殊的編碼格式(如 UTF-8),則在讀取資源內容時(shí)必須事先通過(guò) EncodedResource 指定編碼格式,否則將會(huì )產(chǎn)生中文亂碼的問(wèn)題。


清單 5. EncodedResourceExample
package com.baobaotao.io;                        import org.springframework.core.io.ClassPathResource;                        import org.springframework.core.io.Resource;                        import org.springframework.core.io.support.EncodedResource;                        import org.springframework.util.FileCopyUtils;                        public class EncodedResourceExample {                        public static void main(String[] args) throws Throwable  {                        Resource res = new ClassPathResource("conf/file1.txt");                        // ① 指定文件資源對應的編碼格式(UTF-8)                        EncodedResource encRes = new EncodedResource(res,"UTF-8");                        // ② 這樣才能正確讀取文件的內容,而不會(huì )出現亂碼                        String content  = FileCopyUtils.copyToString(encRes.getReader());                        System.out.println(content);                        }                        }                        

EncodedResource 擁有一個(gè) getResource() 方法獲取 Resource,但該方法返回的是通過(guò)構造函數傳入的原 Resource 對象,所以必須通過(guò) EncodedResource#getReader() 獲取應用編碼后的 Reader 對象,然后再通過(guò)該 Reader 讀取文件的內容。





回頁(yè)首


Web 相關(guān)工具類(lèi)

您幾乎總是使用 Spring 框架開(kāi)發(fā) Web 的應用,Spring 為 Web 應用提供了很多有用的工具類(lèi),這些工具類(lèi)可以給您的程序開(kāi)發(fā)帶來(lái)很多便利。在這節里,我們將逐一介紹這些工具類(lèi)的使用方法。

操作 Servlet API 的工具類(lèi)

當您在控制器、JSP 頁(yè)面中想直接訪(fǎng)問(wèn) Spring 容器時(shí),您必須事先獲取 WebApplicationContext 對象。Spring 容器在啟動(dòng)時(shí)將 WebApplicationContext 保存在 ServletContext的屬性列表中,通過(guò) WebApplicationContextUtils 工具類(lèi)可以方便地獲取 WebApplicationContext 對象。

WebApplicationContextUtils

當 Web 應用集成 Spring 容器后,代表 Spring 容器的 WebApplicationContext 對象將以 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 為鍵存放在 ServletContext 屬性列表中。您當然可以直接通過(guò)以下語(yǔ)句獲取 WebApplicationContext:

WebApplicationContext wac = (WebApplicationContext)servletContext.                        getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);                        

但通過(guò)位于 org.springframework.web.context.support 包中的 WebApplicationContextUtils 工具類(lèi)獲取 WebApplicationContext 更方便:

WebApplicationContext wac =WebApplicationContextUtils.                        getWebApplicationContext(servletContext);                        

當 ServletContext 屬性列表中不存在 WebApplicationContext 時(shí),getWebApplicationContext() 方法不會(huì )拋出異常,它簡(jiǎn)單地返回 null。如果后續代碼直接訪(fǎng)問(wèn)返回的結果將引發(fā)一個(gè) NullPointerException 異常,而 WebApplicationContextUtils 另一個(gè) getRequiredWebApplicationContext(ServletContext sc) 方法要求 ServletContext 屬性列表中一定要包含一個(gè)有效的 WebApplicationContext 對象,否則馬上拋出一個(gè) IllegalStateException 異常。我們推薦使用后者,因為它能提前發(fā)現錯誤的時(shí)間,強制開(kāi)發(fā)者搭建好必備的基礎設施。

WebUtils

位于 org.springframework.web.util 包中的 WebUtils 是一個(gè)非常好用的工具類(lèi),它對很多 Servlet API 提供了易用的代理方法,降低了訪(fǎng)問(wèn) Servlet API 的復雜度,可以將其看成是常用 Servlet API 方法的門(mén)面類(lèi)。

下面這些方法為訪(fǎng)問(wèn) HttpServletRequest 和 HttpSession 中的對象和屬性帶來(lái)了方便:

方法 說(shuō)明
Cookie getCookie(HttpServletRequest request, String name) 獲取 HttpServletRequest 中特定名字的 Cookie 對象。如果您需要創(chuàng )建 Cookie, Spring 也提供了一個(gè)方便的 CookieGenerator 工具類(lèi);
Object getSessionAttribute(HttpServletRequest request, String name) 獲取 HttpSession 特定屬性名的對象,否則您必須通過(guò)request.getHttpSession.getAttribute(name) 完成相同的操作;
Object getRequiredSessionAttribute(HttpServletRequest request, String name) 和上一個(gè)方法類(lèi)似,只不過(guò)強制要求 HttpSession 中擁有指定的屬性,否則拋出異常;
String getSessionId(HttpServletRequest request) 獲取 Session ID 的值;
void exposeRequestAttributes(ServletRequest request, Map attributes) 將 Map 元素添加到 ServletRequest 的屬性列表中,當請求被導向(forward)到下一個(gè)處理程序時(shí),這些請求屬性就可以被訪(fǎng)問(wèn)到了;

此外,WebUtils還提供了一些和ServletContext相關(guān)的方便方法:

方法 說(shuō)明
String getRealPath(ServletContext servletContext, String path) 獲取相對路徑對應文件系統的真實(shí)文件路徑;
File getTempDir(ServletContext servletContext) 獲取 ServletContex 對應的臨時(shí)文件地址,它以 File 對象的形式返回。

下面的片斷演示了使用 WebUtils 從 HttpSession 中獲取屬性對象的操作:

protected Object formBackingObject(HttpServletRequest request) throws Exception {                        UserSession userSession = (UserSession) WebUtils.getSessionAttribute(request,                        "userSession");                        if (userSession != null) {                        return new AccountForm(this.petStore.getAccount(                        userSession.getAccount().getUsername()));                        } else {                        return new AccountForm();                        }                        }                        

Spring 所提供的過(guò)濾器和監聽(tīng)器

Spring 為 Web 應用提供了幾個(gè)過(guò)濾器和監聽(tīng)器,在適合的時(shí)間使用它們,可以解決一些常見(jiàn)的 Web 應用問(wèn)題。

延遲加載過(guò)濾器

Hibernate 允許對關(guān)聯(lián)對象、屬性進(jìn)行延遲加載,但是必須保證延遲加載的操作限于同一個(gè) Hibernate Session 范圍之內進(jìn)行。如果 Service 層返回一個(gè)啟用了延遲加載功能的領(lǐng)域對象給 Web 層,當 Web 層訪(fǎng)問(wèn)到那些需要延遲加載的數據時(shí),由于加載領(lǐng)域對象的 Hibernate Session 已經(jīng)關(guān)閉,這些導致延遲加載數據的訪(fǎng)問(wèn)異常。

Spring 為此專(zhuān)門(mén)提供了一個(gè) OpenSessionInViewFilter 過(guò)濾器,它的主要功能是使每個(gè)請求過(guò)程綁定一個(gè) Hibernate Session,即使最初的事務(wù)已經(jīng)完成了,也可以在 Web 層進(jìn)行延遲加載的操作。

OpenSessionInViewFilter 過(guò)濾器將 Hibernate Session 綁定到請求線(xiàn)程中,它將自動(dòng)被 Spring 的事務(wù)管理器探測到。所以 OpenSessionInViewFilter 適用于 Service 層使用HibernateTransactionManager 或 JtaTransactionManager 進(jìn)行事務(wù)管理的環(huán)境,也可以用于非事務(wù)只讀的數據操作中。

要啟用這個(gè)過(guò)濾器,必須在 web.xml 中對此進(jìn)行配置:

…                        <filter>                        <filter-name>hibernateFilter</filter-name>                        <filter-class>                        org.springframework.orm.hibernate3.support.OpenSessionInViewFilter                        </filter-class>                        </filter>                        <filter-mapping>                        <filter-name>hibernateFilter</filter-name>                        <url-pattern>*.html</url-pattern>                        </filter-mapping>                        …                        

上面的配置,我們假設使用 .html 的后綴作為 Web 框架的 URL 匹配模式,如果您使用 Struts 等 Web 框架,可以將其改為對應的“*.do”模型。

中文亂碼過(guò)濾器

在您通過(guò)表單向服務(wù)器提交數據時(shí),一個(gè)經(jīng)典的問(wèn)題就是中文亂碼問(wèn)題。雖然我們所有的 JSP 文件和頁(yè)面編碼格式都采用 UTF-8,但這個(gè)問(wèn)題還是會(huì )出現。解決的辦法很簡(jiǎn)單,我們只需要在 web.xml 中配置一個(gè) Spring 的編碼轉換過(guò)濾器就可以了:

<web-app>                        <!---listener的配置-->                        <filter>                        <filter-name>encodingFilter</filter-name>                        <filter-class>                        org.springframework.web.filter.CharacterEncodingFilter ① Spring 編輯過(guò)濾器                        </filter-class>                        <init-param> ② 編碼方式                        <param-name>encoding</param-name>                        <param-value>UTF-8</param-value>                        </init-param>                        <init-param> ③ 強制進(jìn)行編碼轉換                        <param-name>forceEncoding</param-name>                        <param-value>true</param-value>                        </init-param>                        </filter>                        <filter-mapping> ② 過(guò)濾器的匹配 URL                        <filter-name>encodingFilter</filter-name>                        <url-pattern>*.html</url-pattern>                        </filter-mapping>                        <!---servlet的配置-->                        </web-app>                        

這樣所有以 .html 為后綴的 URL 請求的數據都會(huì )被轉碼為 UTF-8 編碼格式,表單中文亂碼的問(wèn)題就可以解決了。

請求跟蹤日志過(guò)濾器

除了以上兩個(gè)常用的過(guò)濾器外,還有兩個(gè)在程序調試時(shí)可能會(huì )用到的請求日志跟蹤過(guò)濾器,它們會(huì )將請求的一些重要信息記錄到日志中,方便程序的調試。這兩個(gè)日志過(guò)濾器只有在日志級別為 DEBUG 時(shí)才會(huì )起作用:

方法 說(shuō)明
org.springframework.web.filter.ServletContextRequestLoggingFilter 該過(guò)濾器將請求的 URI 記錄到 Common 日志中(如通過(guò) Log4J 指定的日志文件);
org.springframework.web.filter.ServletContextRequestLoggingFilter 該過(guò)濾器將請求的 URI 記錄到 ServletContext 日志中。

以下是日志過(guò)濾器記錄的請求跟蹤日志的片斷:

(JspServlet.java:224) -     JspEngine --> /htmlTest.jsp                        (JspServlet.java:225) - 	     ServletPath: /htmlTest.jsp                        (JspServlet.java:226) - 	        PathInfo: null                        (JspServlet.java:227) - 	        RealPath: D:\masterSpring\chapter23\webapp\htmlTest.jsp                        (JspServlet.java:228) - 	      RequestURI: /baobaotao/htmlTest.jsp                        …                        

通過(guò)這個(gè)請求跟蹤日志,程度調試者可以詳細地查看到有哪些請求被調用,請求的參數是什么,請求是否正確返回等信息。雖然這兩個(gè)請求跟蹤日志過(guò)濾器一般在程序調試時(shí)使用,但是即使程序部署不將其從 web.xml 中移除也不會(huì )有大礙,因為只要將日志級別設置為 DEBUG 以上級別,它們就不會(huì )輸出請求跟蹤日志信息了。

轉存 Web 應用根目錄監聽(tīng)器和 Log4J 監聽(tīng)器

Spring 在 org.springframework.web.util 包中提供了幾個(gè)特殊用途的 Servlet 監聽(tīng)器,正確地使用它們可以完成一些特定需求的功能。比如某些第三方工具支持通過(guò) ${key} 的方式引用系統參數(即可以通過(guò) System.getProperty() 獲取的屬性),WebAppRootListener 可以將 Web 應用根目錄添加到系統參數中,對應的屬性名可以通過(guò)名為“webAppRootKey”的 Servlet 上下文參數指定,默認為“webapp.root”。下面是該監聽(tīng)器的具體的配置:


清單 6. WebAppRootListener 監聽(tīng)器配置
…                        <context-param>                        <param-name>webAppRootKey</param-name>                        <param-value>baobaotao.root</param-value> ① Web 應用根目錄以該屬性名添加到系統參數中                        </context-param>                        …                        ② 負責將 Web 應用根目錄以 webAppRootKey 上下文參數指定的屬性名添加到系統參數中                        <listener>                        <listener-class>                        org.springframework.web.util.WebAppRootListener                        </listener-class>                        </listener>                        …                        

這樣,您就可以在程序中通過(guò) System.getProperty("baobaotao.root") 獲取 Web 應用的根目錄了。不過(guò)更常見(jiàn)的使用場(chǎng)景是在第三方工具的配置文件中通過(guò)${baobaotao.root} 引用 Web 應用的根目錄。比如以下的 log4j.properties 配置文件就通過(guò) ${baobaotao.root} 設置了日志文件的地址:

log4j.rootLogger=INFO,R                        log4j.appender.R=org.apache.log4j.RollingFileAppender                        log4j.appender.R.File=${baobaotao.root}/WEB-INF/logs/log4j.log ① 指定日志文件的地址                        log4j.appender.R.MaxFileSize=100KB                        log4j.appender.R.MaxBackupIndex=1                        log4j.appender.R.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n                        

另一個(gè)專(zhuān)門(mén)用于 Log4J 的監聽(tīng)器是 Log4jConfigListener。一般情況下,您必須將 Log4J 日志配置文件以 log4j.properties 為文件名并保存在類(lèi)路徑下。Log4jConfigListener 允許您通過(guò) log4jConfigLocation Servlet 上下文參數顯式指定 Log4J 配置文件的地址,如下所示:

① 指定 Log4J 配置文件的地址                        <context-param>                        <param-name>log4jConfigLocation</param-name>                        <param-value>/WEB-INF/log4j.properties</param-value>                        </context-param>                        …                        ② 使用該監聽(tīng)器初始化 Log4J 日志引擎                        <listener>                        <listener-class>                        org.springframework.web.util.Log4jConfigListener                        </listener-class>                        </listener>                        …                        

提示

一些Web應用服務(wù)器(如 Tomcat)不會(huì )為不同的Web應用使用獨立的系統參數,也就是說(shuō),應用服務(wù)器上所有的 Web 應用都共享同一個(gè)系統參數對象。這時(shí),您必須通過(guò)webAppRootKey 上下文參數為不同Web應用指定不同的屬性名:如第一個(gè) Web 應用使用 webapp1.root 而第二個(gè) Web 應用使用 webapp2.root 等,這樣才不會(huì )發(fā)生后者覆蓋前者的問(wèn)題。此外,WebAppRootListener 和 Log4jConfigListener 都只能應用在 Web 應用部署后 WAR 文件會(huì )解包的 Web 應用服務(wù)器上。一些 Web 應用服務(wù)器不會(huì )將Web 應用的 WAR 文件解包,整個(gè) Web 應用以一個(gè) WAR 包的方式存在(如 Weblogic),此時(shí)因為無(wú)法指定對應文件系統的 Web 應用根目錄,使用這兩個(gè)監聽(tīng)器將會(huì )發(fā)生問(wèn)題。

Log4jConfigListener 監聽(tīng)器包括了 WebAppRootListener 的功能,也就是說(shuō),Log4jConfigListener 會(huì )自動(dòng)完成將 Web 應用根目錄以 webAppRootKey 上下文參數指定的屬性名添加到系統參數中,所以當您使用 Log4jConfigListener 后,就沒(méi)有必須再使用 WebAppRootListener了。

Introspector 緩存清除監聽(tīng)器

Spring 還提供了一個(gè)名為 org.springframework.web.util.IntrospectorCleanupListener 的監聽(tīng)器。它主要負責處理由 JavaBean Introspector 功能而引起的緩存泄露。IntrospectorCleanupListener 監聽(tīng)器在 Web 應用關(guān)閉的時(shí)會(huì )負責清除 JavaBean Introspector 的緩存,在 web.xml 中注冊這個(gè)監聽(tīng)器可以保證在 Web 應用關(guān)閉的時(shí)候釋放與其相關(guān)的 ClassLoader 的緩存和類(lèi)引用。如果您使用了 JavaBean Introspector 分析應用中的類(lèi),Introspector 緩存會(huì )保留這些類(lèi)的引用,結果在應用關(guān)閉的時(shí)候,這些類(lèi)以及Web 應用相關(guān)的 ClassLoader 不能被垃圾回收。不幸的是,清除 Introspector 的唯一方式是刷新整個(gè)緩存,這是因為沒(méi)法準確判斷哪些是屬于本 Web 應用的引用對象,哪些是屬于其它 Web 應用的引用對象。所以刪除被緩存的 Introspection 會(huì )導致將整個(gè) JVM 所有應用的 Introspection 都刪掉。需要注意的是,Spring 托管的 Bean 不需要使用這個(gè)監聽(tīng)器,因為 Spring 的 Introspection 所使用的緩存在分析完一個(gè)類(lèi)之后會(huì )馬上從 javaBean Introspector 緩存中清除掉,并將緩存保存在應用程序特定的 ClassLoader 中,所以它們一般不會(huì )導致內存資源泄露。但是一些類(lèi)庫和框架往往會(huì )產(chǎn)生這個(gè)問(wèn)題。例如 Struts 和 Quartz 的 Introspector 的內存泄漏會(huì )導致整個(gè)的 Web 應用的 ClassLoader 不能進(jìn)行垃圾回收。在 Web 應用關(guān)閉之后,您還會(huì )看到此應用的所有靜態(tài)類(lèi)引用,這個(gè)錯誤當然不是由這個(gè)類(lèi)自身引起的。解決這個(gè)問(wèn)題的方法很簡(jiǎn)單,您僅需在 web.xml 中配置 IntrospectorCleanupListener 監聽(tīng)器就可以了:

<listener>                        <listener-class>                        org.springframework.web.util.IntrospectorCleanupListener                        </listener-class>                        </listener>                        





回頁(yè)首


小結

本文介紹了一些常用的 Spring 工具類(lèi),其中大部分 Spring 工具類(lèi)不但可以在基于 Spring 的應用中使用,還可以在其它的應用中使用。使用 JDK 的文件操作類(lèi)在訪(fǎng)問(wèn)類(lèi)路徑相關(guān)、Web 上下文相關(guān)的文件資源時(shí),往往顯得拖泥帶水、拐彎抹角,Spring 的 Resource 實(shí)現類(lèi)使這些工作變得輕松了許多。

在 Web 應用中,有時(shí)你希望直接訪(fǎng)問(wèn) Spring 容器,獲取容器中的 Bean,這時(shí)使用 WebApplicationContextUtils 工具類(lèi)從 ServletContext 中獲取 WebApplicationContext 是非常方便的。WebUtils 為訪(fǎng)問(wèn) Servlet API 提供了一套便捷的代理方法,您可以通過(guò) WebUtils 更好的訪(fǎng)問(wèn) HttpSession 或 ServletContext 的信息。

Spring 提供了幾個(gè) Servlet 過(guò)濾器和監聽(tīng)器,其中 ServletContextRequestLoggingFilter 和 ServletContextRequestLoggingFilter 可以記錄請求訪(fǎng)問(wèn)的跟蹤日志,你可以在程序調試時(shí)使用它們獲取請求調用的詳細信息。WebAppRootListener 可以將 Web 應用的根目錄以特定屬性名添加到系統參數中,以便第三方工具類(lèi)通過(guò) ${key} 的方式進(jìn)行訪(fǎng)問(wèn)。Log4jConfigListener 允許你指定 Log4J 日志配置文件的地址,且可以在配置文件中通過(guò) ${key} 的方式引用 Web 應用根目錄,如果你需要在 Web 應用相關(guān)的目錄創(chuàng )建日志文件,使用 Log4jConfigListener 可以很容易地達到這一目標。

Web 應用的內存泄漏是最讓開(kāi)發(fā)者頭疼的問(wèn)題,雖然不正確的程序編寫(xiě)可能是這一問(wèn)題的根源,也有可能是一些第三方框架的 JavaBean Introspector 緩存得不到清除而導致的,Spring 專(zhuān)門(mén)為解決這一問(wèn)題配備了 IntrospectorCleanupListener 監聽(tīng)器,它只要簡(jiǎn)單在 web.xml 中聲明該監聽(tīng)器就可以了。

在下一篇文章中,我們將繼續介紹 Spring 中用于特殊字符轉義和方法入參檢測相關(guān)的工具類(lèi)。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
spring中常用工具類(lèi)介紹
Spring配置中的“classpath:”與"classpath*:"的區別研究(轉)
Spring環(huán)境搭建之:導入jar包、配置文件名稱(chēng)及放置位置
spring 使用多個(gè)XML配置文件
web.xml 配置中classpath: 與classpath*:的區別
轉:SpringMVC理解之一:應用上下文webApplicationContext
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久