版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
項(xiàng)目十一Servlet高級(jí)特性11.1
Filter在Servlet高級(jí)特性中,F(xiàn)ilter即過濾器。Filter的基本功能是對(duì)Servlet容器調(diào)用Servlet的過程進(jìn)行攔截,它位于客戶端和處理程序之間,能夠?qū)φ?qǐng)求和響應(yīng)進(jìn)行檢查和修改。Filter就好比污水凈化設(shè)備,專門用于過濾請(qǐng)求和響應(yīng)中的“雜質(zhì)”。Filter在Web應(yīng)用中的攔截過程如圖所?示。11.1.1
Filter簡(jiǎn)介Filter在Web應(yīng)用中的攔截過程11.1
Filter1.Filter接口11.1.2
Filter相關(guān)接口表Filter接口中的方法方法功能描述init(FilterConfigfilterConfig)init()方法是Filter的初始化方法,創(chuàng)建Filter實(shí)例后將調(diào)用init()方法。該方法的參數(shù)filterConfig用于讀取Filter的初始化參數(shù)doFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)doFilter()方法負(fù)責(zé)完成實(shí)際的過濾操作,當(dāng)客戶端的請(qǐng)求滿足過濾規(guī)則時(shí),Servlet容器將調(diào)用Filter的doFilter()方法完成實(shí)際的過濾操作。doFilter()方法有多個(gè)參數(shù),其中,參數(shù)request和response為Web服務(wù)器或Filter鏈中的上一個(gè)Filter傳遞過來的請(qǐng)求和響應(yīng)對(duì)象;參數(shù)chain代表當(dāng)前Filter鏈destroy()該方法用于釋放被Filter打開的資源(例如關(guān)閉數(shù)據(jù)庫(kù)和
I/O流)。destroy()方法在Web服務(wù)器銷毀Filter時(shí)被調(diào)用11.1
Filter2.FilterConfig接口表FilterConfig接口中的方法方法功能描述StringgetFilterName()返回Filter的名稱ServletContextgetServletContext()返回FilterConfig對(duì)象中封裝的ServletContext對(duì)象StringgetInitParameter(Stringname)返回名為name的初始化參數(shù)的值EnumerationgetInitParameterNames()返回包含F(xiàn)ilter所有初始化參數(shù)的Enumeration對(duì)象3.FilterChain接口FilterChain接口的doFilter()方法用于調(diào)用Filter鏈中的下一個(gè)過濾器。如果這個(gè)Filter是Filter鏈上的最后一個(gè)Filter,則將請(qǐng)求提交給處理程序或?qū)㈨憫?yīng)發(fā)送給客戶?端。11.1
Filter11.1.3
Filter的生命周期Filter的生命周期指的是一個(gè)Filter對(duì)象從創(chuàng)建到執(zhí)行再到銷毀的過程。Filter接口中的3個(gè)方法就是管理Filter的生命周期的方法。下面依次介紹Filter的生命周期的3個(gè)階?段。Web服務(wù)器啟動(dòng)的時(shí)候會(huì)創(chuàng)建Filter實(shí)例,并調(diào)用init()方法,完成Filter的初始化。需要注意的是,在一次完整的請(qǐng)求當(dāng)中,F(xiàn)ilter實(shí)例只會(huì)創(chuàng)建一次,init()方法也只會(huì)執(zhí)行一?次。01創(chuàng)建階段當(dāng)客戶端請(qǐng)求目標(biāo)資源時(shí),Web服務(wù)器會(huì)篩選出符合映射條件的Filter實(shí)例,并按照類名的先后順序依次執(zhí)行doFilter()方法。02執(zhí)行階段Web服務(wù)器關(guān)閉時(shí)調(diào)用destroy()方法銷毀Filter對(duì)?象。03銷毀階段11.1
Filter11.1.4實(shí)現(xiàn)Filter下面通過一個(gè)案例演示Filter如何對(duì)Servlet容器調(diào)用Servlet過程進(jìn)行攔截。在IDEA中創(chuàng)建名稱為ServletHighDemo的Web項(xiàng)目,在ServletHighDemo項(xiàng)目的srm目錄下創(chuàng)建名稱為DemoServletHigh01的類,其具體代碼如?下。案例
實(shí)現(xiàn)Filter(資源位置:項(xiàng)目11\源文件\DemoServletHigh01.java)importjavax.servlet.ServletException;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;@WebServlet(name="DemoServletHigh01",urlPatterns="/DemoServletHigh01")publicclassDemoServletHigh01extendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{ response.getWriter().println("HelloDemoServletHigh01");}publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{doGet(request,response);}}頁面輸出“HelloDemoServletHigh01”11.1
Filter接下來創(chuàng)建Filter,在ServletHighDemo項(xiàng)目的srm目錄下創(chuàng)建名稱為DemoServletHigh02的Filter類,其具體代碼如?下。案例
實(shí)現(xiàn)Filter(資源位置:項(xiàng)目11\源文件\DemoServletHigh02.java)importjavax.servlet.ServletException;importjavax.servlet.annotation.WebFilter;importjava.io.IOException;importjava.io.PrintWriter;importjavax.servlet.*;@WebFilter(filterName="DemoServletHigh02",urlPatterns="/DemoServletHigh01")publicclassDemoServletHigh02implementsFilter{publicvoidinit(FilterConfigfConfig)throwsServletException{//在初始化時(shí)調(diào)用,可以配置一些初始化參數(shù)}publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{//用于攔截用戶的請(qǐng)求,如果和當(dāng)前Filter的攔截路徑匹配,該方法會(huì)被調(diào)用PrintWriterout=response.getWriter();out.write("HelloDemoServletHigh02Filter");}publicvoiddestroy(){//過濾器對(duì)象在銷毀時(shí)自動(dòng)調(diào)用,釋放資源}}頁面顯示的結(jié)果11.1
FilterDemoServletHigh02.java中用到了@WebFilter注解,該注解的屬性filterName用于設(shè)置Filter的名稱,urlPatterns屬性用于匹配用戶請(qǐng)求的URL。@WebFilter注解的常用屬性如表所?示。屬性名類型描述filterNameString指定Filter的名稱。默認(rèn)是Filter類的名稱urlPatternsString[]指定一組Filter的URL匹配模式valueString[]該屬性等價(jià)于urlPatterns屬性,urlPatterns和value屬性不能同時(shí)使用servletNamesString[]指定Filter將應(yīng)用于哪些Servlet,取值是
@WebServlet中的name屬性的取值dispatcherTypesDispatcherType指定Filter的轉(zhuǎn)發(fā)模式,具體取值包括ERROR、FORWARD、INCLUDE、REQUESTinitParamsWebInitParam[]指定Filter的一組初始化參數(shù)表
@WebFilter注解的常用屬性11.1
Filter11.1.5
Filter映射如果想讓過濾器攔截所有請(qǐng)求,可以使用通配符“/*”實(shí)現(xiàn),即將urlPatterns屬性配置成“/*”。使用通配符“/*”攔截所有請(qǐng)求01在@WebFilter注解有一個(gè)特殊的屬性—dispatcherTypes,它可以指定Filter的轉(zhuǎn)發(fā)模式,dispatcherTypes屬性有4個(gè)常用值:攔截不同訪問方式的請(qǐng)求02REQUEST:如果用戶通過RequestDispatcher對(duì)象的include()方法或forward()方法訪問目標(biāo)資源,那么Filter不會(huì)被調(diào)用。除此之外,該Filter會(huì)被調(diào)?用。INCLUDE:如果用戶通過RequestDispatcher對(duì)象的include()方法訪問目標(biāo)資源,那么Filter將被調(diào)用。除此之外,該Filter不會(huì)被調(diào)?用。FORWARD:如果通過RequestDispatcher對(duì)象的forward()方法訪問目標(biāo)資源,那么Filter將被調(diào)用。除此之外,該Filter不會(huì)被調(diào)?用。ERROR:如果通過聲明式異常處理機(jī)制調(diào)用目標(biāo)資源,那么Filter將被調(diào)用。除此之外,F(xiàn)ilter不會(huì)被調(diào)?用。11.1
Filter在ServletHighDemo項(xiàng)目的srm目錄下創(chuàng)建名稱為DemoServletHigh03的Servlet類,其具體代碼如?下。案例
在ServletHighDemo項(xiàng)目的srm目錄下創(chuàng)建名稱為DemoServletHigh03的Servlet類,其具體代碼如?下。importjavax.servlet.ServletException;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;@WebServlet(name="DemoServletHigh03",urlPatterns="/DemoServletHigh03")publicclassDemoServletHigh03extendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{request.getRequestDispatcher("/DemoServletHigh01.jsp").forward(request,response);}publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{doGet(request,response);}}11.1
Filter在ServletHighDemo項(xiàng)目的Web目錄下創(chuàng)建DemoServletHigh01.jsp頁面,其具體代碼如?下。案例
實(shí)現(xiàn)Filter(資源位置:項(xiàng)目11\源文件\DemoServletHigh01.jsp)<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>DemoServletHigh01.jsp</title><scripttype="text/javascript"src="jquery-3.7.1.js"></script></head><body>DemoServletHigh01.jsp</body></html>在ServletHighDemo項(xiàng)目的srm目錄下創(chuàng)建名稱為DemoServletHigh04的Filter類,其具體代碼如?下。案例
實(shí)現(xiàn)Filter(資源位置:項(xiàng)目11\源文件\DemoServletHigh04.java)11.1
Filterimportjavax.servlet.*;importjavax.servlet.annotation.WebFilter;importjava.io.IOException;importjava.io.PrintWriter;@WebFilter(filterName="DemoServletHigh04",urlPatterns="/DemoServletHigh01.jsp")publicclassDemoServletHigh04implementsFilter{publicvoidinit(FilterConfigfConfig)throwsServletException{//在初始化時(shí)調(diào)用,可以配置一些初始化參數(shù)}publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{//用于攔截用戶的請(qǐng)求,如果和當(dāng)前Filter的攔截路徑匹配,該方法會(huì)被調(diào)用PrintWriterout=response.getWriter();out.write("HelloDemoServletHigh01.jsp");}publicvoiddestroy(){//在銷毀Filter時(shí)自動(dòng)調(diào)用,釋放資源}}在IDEA中啟動(dòng)項(xiàng)目ServletHighDemo,使用瀏覽器訪問地址“http://localhost:8080/DemoServletHigh03”,跳轉(zhuǎn)到DemoServletHigh01.jsp頁面,如圖所?示。11.1
Filter如果要攔截DemoServletHigh03類通過forward()方法轉(zhuǎn)發(fā)到DemoServletHigh01.jsp頁面的請(qǐng)求,可以修改DemoServletHigh04.java中的代碼,在@WebFilter注解中設(shè)置dispatcherTypes屬性值為FORWARD,具體代碼如下:@WebFilter(filterName="ForwardFilter",urlPatterns="/DemoServletHigh01.jsp",dispatcherTypes=DispatcherType.FORWARD)修改之后,再次在IDEA中啟動(dòng)項(xiàng)目ServletHighDemo,使用瀏覽器訪問地址“http://localhost:8080/DemoServletHigh03”,頁面顯示doFilter()里面的輸出信息,如圖所?示。頁面顯示doFilter()里面的輸出信息11.1
Filter11.1.6
Filter鏈在一個(gè)Web應(yīng)用程序中可以注冊(cè)多個(gè)Filter,每個(gè)Filter都可以針對(duì)不同URL的請(qǐng)求進(jìn)行攔截。如果多個(gè)Filter都對(duì)同一個(gè)URL的請(qǐng)求進(jìn)行攔截,那么這些Filter就組成一條Filter鏈。Filter鏈?zhǔn)褂肍ilterChain對(duì)象表示,F(xiàn)ilterChain對(duì)象提供了doFilter()方法,該方法的作用是讓Filter鏈上的當(dāng)前Filter放行請(qǐng)求,使請(qǐng)求進(jìn)入下一個(gè)Filter。Filter鏈的攔截過程(以兩個(gè)Filter為例)如圖所?示。Filter鏈的攔截過程11.2監(jiān)聽器Listener11.2.1監(jiān)聽器Listener簡(jiǎn)介L(zhǎng)istener的監(jiān)聽過程涉及幾個(gè)重要的組成部分,具體如?下。事件:用戶的一個(gè)操作(如單擊一個(gè)按鈕、調(diào)用一個(gè)方法、創(chuàng)建一個(gè)對(duì)象等)。事件源:產(chǎn)生事件的對(duì)?象。事件監(jiān)聽器:負(fù)責(zé)監(jiān)聽發(fā)生在事件源上的事?件。事件處理器:監(jiān)聽器的成員方法,當(dāng)事件發(fā)生的時(shí)候會(huì)觸發(fā)對(duì)應(yīng)的事件處理?器。事件監(jiān)聽器的工作過程可分為以下幾個(gè)步?驟。(1)將監(jiān)聽器綁定到事件源,也就是注冊(cè)監(jiān)聽?器。(2)監(jiān)聽器監(jiān)聽到事件發(fā)生時(shí),會(huì)調(diào)用自己的成員方法,將事件傳遞給事件處理器,即觸發(fā)事件處理?器。(3)事件處理器通過事件獲得事件源,并對(duì)事件源進(jìn)行處?理。11.2監(jiān)聽器Listener11.2.2創(chuàng)建ListenerListener共有8個(gè)不同的監(jiān)聽器接口,分別用于監(jiān)聽不同的對(duì)象,具體如表所?示。名稱描述ServletContextListener用于監(jiān)聽ServletContext對(duì)象的創(chuàng)建和銷毀過程HttpSessionListener用于監(jiān)聽HttpSession對(duì)象的創(chuàng)建和銷毀過程ServletRequestListener用于監(jiān)聽ServletRequest對(duì)象的創(chuàng)建和銷毀過程ServletContextAttributeListener用于監(jiān)聽ServletContext對(duì)象中的屬性變更HttpSessionAttributeListener用于監(jiān)聽HttpSession對(duì)象中的屬性變更ServletRequestAttributeListener用于監(jiān)聽ServletRequest對(duì)象中的屬性變更HttpSessionBindingListener用于監(jiān)聽JavaBean對(duì)象綁定到HttpSession對(duì)象和JavaBean對(duì)象從HttpSession對(duì)象解綁HttpSessionActivationListener用于監(jiān)聽HttpSession中對(duì)象活化和鈍化的過程11.2監(jiān)聽器ListenerListener的8種Servlet事件監(jiān)聽器可以分為3類,具體如?下。(1)用于監(jiān)聽域?qū)ο髣?chuàng)建和銷毀過程的Listener:ServletContextListener、HttpSessionListener和ServletRequestListener。(2)用于監(jiān)聽域?qū)ο髮傩宰兏谋O(jiān)聽器:ServletContextAttributeListener、HttpSession-AttributeListener和ServletRequestAttributeListener。(3)用于監(jiān)聽綁定到HttpSession對(duì)象的某個(gè)對(duì)象的狀態(tài)變化的事件監(jiān)聽器:HttpSession-BindingListener和HttpSessionActivationListener。11.2監(jiān)聽器Listener在ServletHighDemo項(xiàng)目的srm目錄下創(chuàng)建名稱為DemoServletHigh05的Listener類,其具體代碼如?下。importjavax.servlet.ServletContextEvent;importjavax.servlet.ServletContextListener;importjavax.servlet.ServletRequestEvent;importjavax.servlet.ServletRequestListener;importjavax.servlet.annotation.WebListener;importjavax.servlet.http.HttpSessionEvent;importjavax.servlet.http.HttpSessionListener;@WebListenerpublicclassDemoServletHigh05implementsServletContextListener,HttpSessionListener,ServletRequestListener{publicvoidcontextInitialized(ServletContextEventarg0){System.out.println("ServletContext對(duì)象被創(chuàng)建了");}publicvoidcontextDestroyed(ServletContextEventarg0){System.out.println("ServletContext對(duì)象被銷毀了");}publicvoidrequestInitialized(ServletRequestEventservletRequestEvent){System.out.println("ServletRequestEvent對(duì)象被創(chuàng)建了");}publicvoidrequestDestroyed(ServletRequestEventservletRequestEvent){System.out.println("ServletRequestEvent對(duì)象被銷毀了");}publicvoidsessionCreated(HttpSessionEventhttpSessionEvent){System.out.println("HttpSessionEvent對(duì)象被創(chuàng)建了");}publicvoidsessionDestroyed(HttpSessionEventhttpSessionEvent){System.out.println("HttpSessionEvent對(duì)象被銷毀了");}}案例
ServletContext對(duì)象(資源位置:項(xiàng)目11\源文件\DemoServletHigh05.java)11.2監(jiān)聽器Listener在IDEA中啟動(dòng)項(xiàng)目ServletHighDemo,IDEA控制臺(tái)輸出“ServletContext對(duì)象被創(chuàng)建了”,如圖所?示。為了查看ServletContext對(duì)象的銷毀信息,可以將已經(jīng)啟動(dòng)的Web服務(wù)器關(guān)閉,關(guān)閉Web服務(wù)器之后,IDEA控制臺(tái)輸出“ServletContext對(duì)象被銷毀了”,窗口顯示的結(jié)果如圖所?示。IDEA控制臺(tái)輸出“ServletContext對(duì)象被創(chuàng)建了”IDEA控制臺(tái)輸出“ServletContext對(duì)象被銷毀了”11.2監(jiān)聽器Listener為了查看HttpSessionListener和ServletRequestListener的運(yùn)行效果,在ServletHighDemo項(xiàng)目的Web目錄下創(chuàng)建名稱為DemoServletHigh02.jsp的頁面,其具體代碼如?下。案例
ServletContext對(duì)象(資源位置:項(xiàng)目11\源文件\DemoServletHigh02.jsp)<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>DemoServletHigh02.jsp</title></head><body>
這是一個(gè)測(cè)試監(jiān)聽器的頁面</body></html>為了盡快查看到HttpSessionEvent對(duì)象創(chuàng)建和銷毀,可以在ServletHighDemo項(xiàng)目的Web.xml文件中設(shè)置session的超時(shí)時(shí)間為2分鐘,具體代碼如?下。<session-config><session-timeout>2</session-timeout></session-config>11.2監(jiān)聽器Listener重新啟動(dòng)項(xiàng)目ServletHighDemo,再打開瀏覽器,在地址欄中輸入“http://localhost:8080/DemoServletHigh02.jsp”,并按“Enter”鍵。IDEA控制臺(tái)輸出與ServletRequestEvent對(duì)象相關(guān)的內(nèi)容,如圖所示。IDEA控制臺(tái)輸出與ServletRequestEvent對(duì)象相關(guān)的內(nèi)容對(duì)應(yīng)的HttpSessionEvent對(duì)象將在2分鐘之后被銷毀,IDEA控制臺(tái)輸出“HttpSessionEvent對(duì)象被銷毀了”,如下圖所?示。IDEA控制器輸出“HttpSessionEvent對(duì)象被銷毀了”11.3文件的上傳11.3.1文件上傳原理在Web開發(fā)中,要實(shí)現(xiàn)文件上傳功能,通常需要完成兩步操作:一是在Web項(xiàng)目的頁面中添加文件上傳輸入項(xiàng);二是在Servlet中讀取上傳文件的數(shù)據(jù),并保存到目標(biāo)路徑?中。<inputtype="file">標(biāo)簽的使用需要注意以下兩?點(diǎn)。<%--指定<form>標(biāo)簽的enctype屬性和method屬性--%><formenctype="multipart/form-data"method="post"> <%--指定<input>標(biāo)簽的type屬性和name屬性--%>
選擇上傳文件:<inputtype="file"name="myfile"/><br/></form>必須要設(shè)置<input>標(biāo)簽的name屬性,否則瀏覽器將不會(huì)向服務(wù)器發(fā)送上傳文件的數(shù)?據(jù)。必須把將<form>標(biāo)簽的enctype屬性設(shè)置為“multipart/form-data”,method屬性設(shè)置為“post”。需要注意的是,在使用Commons-FileUpload組件時(shí),需要導(dǎo)入commons-fileupload.jar和commons-io.jar兩個(gè)JAR包。11.3文件的上傳1.FileItem接口11.3.2認(rèn)識(shí)Commons-FileUpload組件FileItem接口主要用于封裝單個(gè)表單字段元素的數(shù)據(jù),一個(gè)表單字段元素對(duì)應(yīng)一個(gè)FileItem對(duì)象。Commons-FileUpload組件在處理文件上傳時(shí),將每一個(gè)表單域(包括普通文本表單域和文件域)封裝在一個(gè)FileItem對(duì)象?中。方法聲明功能描述booleanisFormField()isFormField()方法用于判斷FileItem對(duì)象封裝的是一個(gè)普通文本表單字段,還是一個(gè)文件表單字段,如果是普通文本表單字段則返回true,否則返回falseStringgetName()getName()方法用于獲取文件上傳字段中的文件名。如果FileItem對(duì)象對(duì)應(yīng)的是普通文本表單字段,getName()方法將返回null;否則,只要瀏覽器將文件的字段信息傳遞給服務(wù)器,getName()方法就會(huì)返回一個(gè)String類型的結(jié)果(如“C:\Sunset.jpg”)StringgetFieldName()getFieldName()方法用于獲取表單字段元素描述頭的name屬性值,也是<form>標(biāo)簽name屬性的值。例如“name=file1”中的“file1”表FileItem類的方法11.3文件的上傳方法聲明功能描述voidwrite(Filefile)write()方法用于將FileItem對(duì)象中保存的主體內(nèi)容保存到某個(gè)指定的文件中。如果FileItem對(duì)象中的主體內(nèi)容保存在某個(gè)臨時(shí)文件中,那么該方法調(diào)用成功后,臨時(shí)文件有可能會(huì)被清除。另外,該方法也可將普通文本表單字段內(nèi)容寫入一個(gè)文件中,但它主要用于將上傳的文件內(nèi)容保存到本地文件系統(tǒng)中StringgetString()getString()方法用于將FileItem對(duì)象中保存的主體內(nèi)容以字符串的形式返回。它有兩個(gè)重載的定義形式:①publicStringgetString();②publicStringgetString(java.lang.Stringencoding)。前者使用默認(rèn)的字符編碼將主體內(nèi)容轉(zhuǎn)換成字符串,后者使用encoding參數(shù)指定的字符編碼將主體內(nèi)容轉(zhuǎn)換成字符串StringgetContentType()getContentType()方法用于獲得上傳文件的類型,即表單字段元素描述頭屬性Content-Type的值(如“image/jpeg”)。如果FileItem對(duì)象對(duì)應(yīng)的是普通文本表單字段,該方法將返回null續(xù)表11.3文件的上傳2.DiskFileItemFactory類DiskFileItemFactory類用于將請(qǐng)求消息實(shí)體內(nèi)容中的每一個(gè)文件封裝成單獨(dú)的FileItem對(duì)象。如果上傳的文件比較小,則將其直接保存在內(nèi)存中;如果上傳的文件比較大,則會(huì)以臨時(shí)文件的形式,將其保存在磁盤的臨時(shí)文件夾中。表DiskFileItemFactory類的構(gòu)造方法方法聲明功能描述DiskFileItemFactory()采用默認(rèn)的大小臨界值和系統(tǒng)臨時(shí)文件夾構(gòu)造文件項(xiàng)工廠對(duì)象DiskFileItemFactory(intsizeThreshold,F(xiàn)ilerepository)采用參數(shù)指定的大小臨界值和系統(tǒng)臨時(shí)文件夾構(gòu)造文件項(xiàng)工廠對(duì)象3.ServletFileUpload類ServletFileUpload類是Apache組件處理文件上傳請(qǐng)求的核心高級(jí)類。通過調(diào)用parseRequest(HttpServletRequest)方法,它可以將HTML中每個(gè)表單提交的數(shù)據(jù)封裝成一個(gè)FileItem對(duì)象,然后以List列表的形式返回。表ServletFileUpload類的構(gòu)造方法方法聲明功能描述ServletFileUpload()構(gòu)造一個(gè)未初始化的ServletFileUpload對(duì)象ServletFileUpload(FileItemFactoryfileItemFactory)根據(jù)參數(shù)指定的FileItemFactory對(duì)象構(gòu)造一個(gè)ServletFileUpload對(duì)象11.3文件的上傳11.3.3使用Commons-FileUpload組件要實(shí)現(xiàn)文件上傳功能,需要使用CommonsFileUpload組件,并將JSP頁面<form>標(biāo)簽的enctype屬性值設(shè)置為“multipart/form-data”,再在Servlet中使用I/O流實(shí)現(xiàn)文件的上?傳。下面通過一個(gè)案例演示文件上傳功能的實(shí)現(xiàn)。在ServletHighDemo項(xiàng)目的Web目錄下創(chuàng)建名稱為DemoServletHigh03.jsp的頁面,具體代碼如?下。案例
文件上傳功能的實(shí)現(xiàn)(資源位置:項(xiàng)目11\源文件\DemoServletHigh03.jsp)<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>DemoServletHigh03.jsp</title></head><body><formaction="DemoServletHigh06"method="post"enctype="multipart/form-data"><tablewidth="600px"><tr><td>上傳者</td><td><inputtype="text"name="name"/></td></tr><tr><td>上傳文件</td><td><inputtype="file"name="myfile"></td></tr><tr><tdcolspan="2"><inputtype="submit"value="上傳"/></td></tr></table></form></body></html>11.3文件的上傳在ServletHighDemo項(xiàng)目的srm目錄下創(chuàng)建名稱為DemoServletHigh06的Servlet類,其具體代碼如下。importmons.fileupload.FileItem;importmons.fileupload.disk.DiskFileItemFactory;importmons.fileupload.servlet.ServletFileUpload;importjavax.servlet.ServletException;importjavax.servlet.annotation.MultipartConfig;importjavax.servlet.annotation.WebServlet;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.*;importjava.util.List;importjava.util.UUID;@WebServlet(name="DemoServletHigh06",urlPatterns="/DemoServletHigh06")@MultipartConfigpublicclassDemoServletHigh06extendsHttpServlet{privatestaticfinallongserialVersionUID=1L;publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{案例
文件上傳功能的實(shí)現(xiàn)(資源位置:項(xiàng)目11\源文件\DemoServletHigh06.java)11.3文件的上傳try{//設(shè)置Content-Type字段值response.setContentType("text/html;charset=utf-8");//創(chuàng)建DiskFileItemFactory工廠對(duì)象DiskFileItemFactoryfactory=newDiskFileItemFactory();//設(shè)置文件緩存目錄,如果該目錄不存在則創(chuàng)建Filef=newFile("E:\\TempFolder");if(!f.exists()){f.mkdirs();}//設(shè)置文件的緩存路徑factory.setRepository(f);//創(chuàng)建ServletFileUpload對(duì)象ServletFileUploadfileupload=newServletFileUpload(factory);//設(shè)置字符編碼fileupload.setHeaderEncoding("utf-8");//解析request,得到上傳文件的FileItem對(duì)象List<FileItem>fileitems=fileupload.parseRequest(request);//獲取字符流PrintWriterwriter=response.getWriter();//遍歷集合for(FileItemfileitem:fileitems){//判斷是否為普通字段if(fileitem.isFormField()){//獲得字段名和字段值Stringname=fileitem.getFieldName();if(name.equals("name")){//如果文件不為空,將其保存在value中if(!fileitem.getString().equals("")){Stringvalue=fileitem.getString("utf-8");writer.print("上傳者:"+value+"<br/>");}}}else{//獲取上傳文件的名稱Stringfilename=fileitem.getName();//處理上傳文件if(filename!=null&&!filename.equals("")){11.3文件的上傳writer.print("上傳文件的名稱是:"+filename+"<br/>");//截取出文件名filename=filename.substring(filename.lastIndexOf("\\")+1);//文件名需要唯一filename=UUID.randomUUID().toString()+"_"+filename;//在服務(wù)器中創(chuàng)建同名文件StringWebPath="E:\\workspace\\ServletHighDemo\\upload\\";//將服務(wù)器中文件夾路徑與文件的名稱組合成完整的服務(wù)器端路徑Stringfilepath=WebPath+filename;//創(chuàng)建文件
Filefile=newFile(filepath);file.getParentFile().mkdirs();file.createNewFile();//獲得上傳文件流InputStreamin=fileitem.getInputStream();//使用FileOutputStream()打開服務(wù)器端的上傳文件FileOutputStreamout=newFileOutputStream(file);//流的復(fù)制byte[]buffer=newbyte[1024];//每次讀取1個(gè)字節(jié)intlen;11.3文件的上傳//開始讀取上傳文件的內(nèi)容,并將其輸出到服務(wù)器的上傳文件輸出流中while((len=in.read(buffer))>0)out.write(buffer,0,len);//關(guān)閉流in.close();out.close();//刪除臨時(shí)文件fileitem.delete();writer.print("上傳文件成功!<br/>");writer.print("上傳的路徑為:"+filepath);}}}}catch(Exceptione){thrownewRuntimeException(e);}}publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{ doGet(request,response);}}選擇要上傳的文件在地址欄中輸入“http://localhost:8080/DemoServletHigh03.jsp”,并按“Enter”鍵來訪問頁面。在頁面中填寫“上傳者”的內(nèi)容,選擇要上傳的文件,如圖所?示。11.3文件的上傳單擊頁面中的“上傳”按鈕,頁面會(huì)顯示文件上傳成功的信息,如圖所?示。在計(jì)算機(jī)中進(jìn)入上圖的文件上傳路徑,查看上傳的文件,如圖所?示。文件上傳成功的信息查看上傳的文件【商業(yè)實(shí)例】仿公司OA管理系統(tǒng)實(shí)現(xiàn)登錄攔截任務(wù)一修改登錄的Servlet類,在登錄成功后往HttpServletResponse中插入cookie值在LoginServlet類中添加如下代?碼。(代碼位置:項(xiàng)目11\商業(yè)實(shí)例\LoginServlet.java)//往HttpServletResponse對(duì)象中插入cookieCookiecookie=newCookie("samCookie",name);response.addCookie(cookie);任務(wù)二
創(chuàng)建LoginFilter,攔截請(qǐng)求創(chuàng)建LoginFilter,如果從HttpServletRequest對(duì)象中未能獲取到登錄成功后插入的cookie值,則跳轉(zhuǎn)到登錄頁?面。(代碼位置:項(xiàng)目11\商業(yè)實(shí)例\LoginFilter.java)importjavax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.Cookie;【商業(yè)實(shí)例】仿公司OA管理系統(tǒng)實(shí)現(xiàn)登錄攔截importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;importjava.util.Arrays;importjava.util.List;@WebFilter(filterName="LoginFilter",urlPatterns="/*")publicclassLoginFilterimplementsFilter{//設(shè)置不被攔截的路徑privatestaticfinalList<String>unFilterUrlList=Arrays.asList("/LoginServlet","/RegisterServlet","/login.jsp","/register.jsp");/*判斷請(qǐng)求路徑是否為不被攔截的路徑*/privatebooleanisFilter(Stringurl){for(Strings:unFilterUrlList){if(url.contains(s)){returnfalse;}}returntrue;}publicvoidinit(FilterConfigfConfig)throwsServletException{//在初始化時(shí)調(diào)用,可以配置一些初始化參數(shù)}publicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainchain)throwsIOException,ServletException{HttpServletRequestrequest=(HttpServletRequest)servletRequest;【商業(yè)實(shí)例】仿公司OA管理系統(tǒng)實(shí)現(xiàn)登錄攔截HttpServletResponseresponse=(HttpServletResponse)servletResponse;response.setContentType("application/json;charset=UTF-8");booleanfilter=isFilter(request.getRequestURL().toString());if(filter){Cookie[]cookies=request.getCookies();if(cookies!=null){booleanflag=false;for(Cookiecookie1:cookies){if(cookie1.getName().equals("samCookie")){flag=true;break;}else{flag=false;}}if(!flag){response.sendRedirect("/login.jsp");}else{chain.doFilter(request,response);}}else{response.sendRedirect("/login.jsp");}}else{chain.doFilter(request,response);}}publicvoiddestroy(){//Filter在銷毀時(shí)自動(dòng)調(diào)用,釋放資源}}登錄頁面項(xiàng)目小結(jié)本項(xiàng)目主要講解了Servlet高級(jí)特性的相關(guān)知?識(shí)。首先講解了Filter,包括Filter的基本知識(shí)、Filter相關(guān)接口、Filter的生命周期、實(shí)現(xiàn)Filter、Filter映射和Filter鏈。之后講解了Listener,包括Listener的基本知識(shí)和創(chuàng)建監(jiān)聽?器。最后講解了文件上傳原理以及CommonsFileUpload的相關(guān)知?識(shí)。通過對(duì)本項(xiàng)目的學(xué)習(xí),讀者應(yīng)該能熟練掌握Servlet高級(jí)特性的相關(guān)知?識(shí)。綜合實(shí)訓(xùn)下面通過綜合實(shí)訓(xùn)讓讀者對(duì)Listener的使用有更加深入的理?解。使用Listener,實(shí)現(xiàn)監(jiān)聽會(huì)話一、實(shí)訓(xùn)目的(1)更深入地了解Servlet高級(jí)特性中Listener的工作原理,以及Listener在Web應(yīng)用程序的開發(fā)中扮演著什么樣的重要角?色。(2)通過動(dòng)手實(shí)踐,將理論知識(shí)應(yīng)用于實(shí)際操作,提升編程實(shí)踐能?力。二、實(shí)訓(xùn)內(nèi)容Listener用于監(jiān)聽Web應(yīng)用程序中的事件(如上下文初始化、會(huì)話創(chuàng)建等)。將創(chuàng)建Listener,用于監(jiān)聽會(huì)話的創(chuàng)建和銷毀事件,統(tǒng)計(jì)會(huì)話?數(shù)。(1)創(chuàng)建名稱為UserCounterListener的Listener,實(shí)現(xiàn)統(tǒng)計(jì)會(huì)話?數(shù)。importjavax.servlet.annotation.WebListener;importjavax.servlet.http.HttpSessionEvent;importjavax.servlet.http.HttpSessionListener;綜合實(shí)訓(xùn)使用Listener,實(shí)現(xiàn)監(jiān)聽會(huì)話@WebListenerpublicclassUserCounterListenerimplementsHttpSessionListener{//使用一個(gè)靜態(tài)變量來統(tǒng)計(jì)會(huì)話數(shù)privatestaticintactiveSessions=0;publicvoidsessionCreated(HttpSessionEventse){activeSessions++;}publicvoidsessionDestroyed(HttpSessionEventhttpSessionEvent){if(activeSessactiveSessions--;}}//添加一個(gè)靜態(tài)方法用于獲取當(dāng)前的會(huì)話數(shù)publicstaticintgetActiveSessions(){returnactiveSessions;}}(2)創(chuàng)建delete.jsp頁面,實(shí)現(xiàn)銷毀會(huì)?話。<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>ys在線人數(shù)</title></head>綜合實(shí)訓(xùn)使用Listener,實(shí)現(xiàn)監(jiān)聽會(huì)話<body>銷毀session<%request.getSession().invalidate();%></body></html>(3)創(chuàng)建名稱為UserListenerServletHigh的Ser
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 河南新高考真題試卷及答案
- 第七單元 第30課時(shí) 視圖與投影
- 初三單元?dú)v史試卷及答案
- 課程培訓(xùn)學(xué)員合同范本
- 2025年生態(tài)環(huán)保部考試題及答案
- 正規(guī)的建筑合同范本
- 第九類綜合考試題及答案
- 遼寧高校招聘試題及答案
- 配件銷售年度合同范本
- 喚醒護(hù)理與家屬溝通
- 2026年電商活動(dòng)策劃實(shí)戰(zhàn)培訓(xùn)課件
- 2026年全國(guó)煙花爆竹經(jīng)營(yíng)單位主要負(fù)責(zé)人考試題庫(kù)(含答案)
- 防范非計(jì)劃性拔管
- 2025年考研政治《馬克思主義基本原理》模擬卷
- (新教材)部編人教版三年級(jí)上冊(cè)語文 第25課 手術(shù)臺(tái)就是陣地 教學(xué)課件
- 2026天津農(nóng)商銀行校園招聘考試歷年真題匯編附答案解析
- 2025重慶市環(huán)衛(wèi)集團(tuán)有限公司招聘27人筆試歷年參考題庫(kù)附帶答案詳解
- 鉆井安全操作規(guī)程
- 精密減速機(jī)行業(yè)發(fā)展現(xiàn)狀及趨勢(shì)預(yù)測(cè)報(bào)告2026-2032
- 中小學(xué)《信息技術(shù)》考試試題及答案
- 2025及未來5年掛鐘機(jī)芯項(xiàng)目投資價(jià)值分析報(bào)告
評(píng)論
0/150
提交評(píng)論