Java web开发——Servlet详细介绍
一、第一個Servlet程序
1、創(chuàng)建Servlet程序
在webapps目錄下新建一個serfis的web應(yīng)用,在serfis下新建一個WEB-INF\classes,在classes新建servlet(FirstServlet.java)
package com.shen; import java.io.*; import javax.servlet.*;public class FirstServlet extends GenericServlet{public void service(ServletRequest req,ServletResponse res)throws ServletException,java.io.IOException{String data = "hello servlet!!";OutputStream out = res.getOutputStream();out.write(data.getBytes()); } }?
2、編譯Servlet程序
? ? ?在cmd中進入classes目錄,編譯FirstServlet(cd/)
javac -d . FirstServlet.javaset classpath=%classpath%;.............(.......為servlet的jar包存放的路徑,因為默認的jar包只包含javaSE)將jar文件直接拖向cmd窗口3、配置Servlet
? ? ?在serfis\web-inf目錄,新建一個web.xml文件,對servlet進行配置
<web-app xmls="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"><servlet><servlet-name>FirstServlet</servlet-name><!--自己取一個Servlet的名--><servlet-class>com.shen.FirstServlet</servlet-class></servlet><servlet-mapping><servlet-name>FirstServlet</servlet-name><url-pattern>/xxx</url-pattern><表示將該Servlet(FirstServlet)映射到xxx下(因為瀏覽器通過url訪問),/表示當前web項目根目錄></servlet-mapping></web-app>?
4、訪問
? ? ?啟動服務(wù)器,在ie輸入http://localhost:8080/serfis/xxx
?
二、Servlet的生命周期
1、詳情說明
1).構(gòu)造器: 只被調(diào)用一次. 只有第一次請求 Servlet 時, 創(chuàng)建 Servlet 的實例. 調(diào)用構(gòu)造器. (這說明 Serlvet 的單實例的!)
2). init 方法: 只被調(diào)用一次. 在創(chuàng)建好實例后立即被調(diào)用. 用于初始化當前 Servlet.?
3). service: 被多次調(diào)用. 每次請求都會調(diào)用 service 方法. 實際用于響應(yīng)請求的.?
4). destroy: 只被調(diào)用一次. 在當前 Servlet 所在的 WEB 應(yīng)用被卸載前調(diào)用. 用于釋放當前 Servlet 所占用的資源.?
?
注意:在Servlet的整個生命周期內(nèi),Servlet的init方法只被調(diào)用一次。而對一個Servlet的每次訪問請求都導(dǎo)致Servlet引擎調(diào)用一次servlet的service方法。service對象在servlet生命周期中服務(wù)器只創(chuàng)建一次,并存在Tomcat服務(wù)器中,之后再調(diào)用該service取之前創(chuàng)建好的對象。對于每次訪問請求,Servlet引擎都會創(chuàng)建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應(yīng)對象,然后將這兩個對象作為參數(shù)傳遞給它調(diào)用的Servlet的service()方法,service方法再根據(jù)請求方式分別調(diào)用doXXX方法。?
?
2、運行原理
? ??
三、Servlet接口及派生類
1、Servlet接口
1.基本概念
? ? ?Sun公司在其API中提供了一個servlet接口,用戶若想用發(fā)一個動態(tài)web資源(即開發(fā)一個Java程序向瀏覽器輸出數(shù)據(jù)),需要完成以下2個步驟:
編寫一個Java類,實現(xiàn)servlet接口。
把開發(fā)好的Java類部署到web服務(wù)器中。
2.程序舉例
public class Servletan implements Servlet {@Overridepublic void destroy() {//web應(yīng)用被卸載時調(diào)用// TODO 自動生成的方法存根System.out.println("destroy");}@Overridepublic ServletConfig getServletConfig() {封裝了Servlet配置,并可以獲取相關(guān)內(nèi)容屬性:servletcontextservletConfig...// TODO 自動生成的方法存根System.out.println("getServletConfig");return null;}@Overridepublic String getServletInfo() {// TODO 自動生成的方法存根System.out.println("getServletInfo");return null;}@Overridepublic void init(ServletConfig arg0) throws ServletException {//用于初始化,只調(diào)用一次// TODO 自動生成的方法存根System.out.println("init");}@Overridepublic void service(ServletRequest arg0, ServletResponse arg1)//實際用于響應(yīng)請求throws ServletException, IOException {// TODO 自動生成的方法存根System.out.println("service");}public void hello(){System.out.println("hello");} }2、HttpServlet實現(xiàn)類
1.基礎(chǔ)概念
? ? ?HttpServlet指能夠處理HTTP請求的servlet,它在原有Servlet接口上添加了一些與HTTP協(xié)議處理方法,它比Servlet接口的功能更為強大。因此開發(fā)人員在編寫Servlet時,通常應(yīng)繼承這個類,而避免直接去實現(xiàn)Servlet接口。
? ? ?HttpServlet在實現(xiàn)Servlet接口時,覆寫了service方法,該方法體內(nèi)的代碼會自動判斷用戶的請求方式,如為GET請求,則調(diào)用HttpServlet的doGet方法,如為Post請求,則調(diào)用doPost方法。因此,開發(fā)人員在編寫Servlet時,通常只需要覆寫doGet或doPost方法,而不要去覆寫service方法。
2.程序舉例
public class HttpServletan extends HttpServlet {@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("hahhah!!");}public void doGet(HttpServletRequest request, HttpServletResponse response)//get請求的響應(yīng)throws ServletException, IOException {response.getOutputStream().write("hahhaha".getBytes());}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);//post請求交由get的請求響應(yīng)}}?
3、GenericServlet實現(xiàn)類
四、servlet的配置
? ? ?在web.xml文件中配置,現(xiàn)有web程序為javaweb,有FirstServlet.java,
1、配置servlet實例
<servlet><!-- Servlet 注冊的名字 --><servlet-name>FirstServlet</servlet-name><!-- Servlet 的全類名 --><servlet-class>com.shen.FirstServlet</servlet-class></servlet>?
注意:可以通過load-on-startup參數(shù)來設(shè)置Serlvet 被創(chuàng)建的時機(即init()方法被調(diào)用的時間):若為負數(shù), 則在第一次請求時被創(chuàng)建.若為 0 或正數(shù), 則在當前 WEB 應(yīng)用被
Serlvet 容器加載時創(chuàng)建實例, 且數(shù)組越小越早被創(chuàng)建.
<servlet><!-- Servlet 注冊的名字 --><servlet-name>FirstServlet</servlet-name><!-- Servlet 的全類名 --><servlet-class>com.shen.FirstServlet</servlet-class><!-- 可以指定 Servlet 被創(chuàng)建的時機 --><load-on-startup>2</load-on-startup></servlet>2、將servlet實例映射到url
1.常規(guī)映射
<servlet-mapping><servlet-name>FirstServlet</servlet-name><url-pattern>/a.servlet</url-pattern><!---即通過訪問localhost:8080/javaweb/a.servlet來訪問該servlet--> </servlet-mapping>注意:
1). 同一個Servlet可以被映射到多個URL上,即多個<servlet-mapping>元素的<servlet-name>子元素的設(shè)置值可以是同一個Servlet的注冊名。一個Servlet僅僅是為一個頁面進行服務(wù),它本身并不代表一個頁面。
如:
<servlet-mapping><servlet-name>FirstServlet</servlet-name><url-pattern>/a.servlet</url-pattern><!---即通過訪問localhost:8080/javaweb/a.servlet來訪問該servlet--> </servlet-mapping><servlet-mapping><servlet-name>FirstServlet</servlet-name><url-pattern>/b.servlet</url-pattern><!---即通過訪問localhost:8080/javaweb/b.servlet來訪問該servlet--> </servlet-mapping>2.通配映射
? ? ?在Servlet映射到的URL中也可以使用*通配符,但是只能有兩種固定的格式:一種格式是“*.擴展名”,另一種格式是以正斜杠(/)開頭并以“/*”結(jié)尾。
//格式1 <servlet-mapping><servlet-name>FirstServlet</servlet-name><url-pattern>*.do</url-pattern><!---即通過訪問localhost:8080/javaweb/fsdf.do來訪問該servlet--> </servlet-mapping>//格式2 <servlet-mapping><servlet-name>FirstServlet</servlet-name><url-pattern>/*</url-pattern><!---即通過訪問localhost:8080/javaweb/fhgdf來訪問該servlet--> </servlet-mapping>注意:
1).?以下的既帶 / 又帶擴展名的不合法.?
<servlet-mapping><servlet-name>secondServlet</servlet-name><url-pattern>/*.action</url-pattern> </servlet-mapping>2). 哪個長得像映射哪個,"/"的優(yōu)先級高于"*"
如:Servlet1 映射到 /abc/*?
Servlet2 映射到 /*?
Servlet3 映射到 /abc?
Servlet4 映射到 *.do?
?
問題:
當請求URL為“/abc/a.html”,“/abc/*”和“/*”都匹配,哪個servlet響應(yīng)?
Servlet引擎將調(diào)用Servlet1。
當請求URL為“/abc”時,“/abc/*”和“/abc”都匹配,哪個servlet響應(yīng)?
Servlet引擎將調(diào)用Servlet3。
當請求URL為“/abc/a.do”時,“/abc/*”和“*.do”都匹配,哪個servlet響應(yīng)?
Servlet引擎將調(diào)用Servlet1。
當請求URL為“/a.do”時,“/*”和“*.do”都匹配,哪個servlet響應(yīng)?
Servlet引擎將調(diào)用Servlet2。
當請求URL為“/xxx/yyy/a.do”時,“/*”和“*.do”都匹配,哪個servlet響應(yīng)?
Servlet引擎將調(diào)用Servlet2。
3.缺省映射
? ? ?如果某個Servlet的映射路徑僅僅為一個正斜杠(/),那么這個Servlet就成為當前Web應(yīng)用程序的缺省Servlet。凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它們的訪問請求都將交給缺省Servlet處理,也就是說,缺省Servlet用于處理所有其他Servlet都不處理的訪問請求(如錯誤頁面的處理)。?
<servlet-mapping><servlet-name>FirstServlet</servlet-name><url-pattern>/</url-pattern><!---即可以通過訪問localhost:8080/javaweb/fhgdff'f來訪問該servlet--> </servlet-mapping>注意:在<tomcat的安裝目錄>\conf\web.xml文件中,注冊了一個名稱為org.apache.catalina.servlets.DefaultServlet的Servlet,并將這個Servlet設(shè)置為了缺省Servlet。當訪問Tomcat服務(wù)器中的某個靜態(tài)HTML文件和圖片時,實際上是在訪問這個缺省Servlet(因為一個靜態(tài)頁面無需自己再配置一個servlet對其進行進行服務(wù))。
五、servlet線程安全
- 當多個客戶端并發(fā)訪問同一個Servlet時,web服務(wù)器會為每一個客戶端的訪問請求創(chuàng)建一個線程,并在這個線程上調(diào)用Servlet的service方法,因此service方法內(nèi)如果訪問了同一個資源的話,就有可能引發(fā)線程安全問題。
- 如果某個Servlet實現(xiàn)了SingleThreadModel接口,那么Servlet引擎將以單線程模式來調(diào)用其service方法。
- SingleThreadModel接口中沒有定義任何方法,只要在Servlet類的定義中增加實現(xiàn)SingleThreadModel接口的聲明即可。對于實現(xiàn)了SingleThreadModel接口的Servlet,Servlet引擎仍然支持對該Servlet的多線程并發(fā)訪問,其采用的方式是產(chǎn)生多個Servlet實例對象,并發(fā)的每個線程分別調(diào)用一個獨立的Servlet實例對象。
- 實現(xiàn)SingleThreadModel接口并不能真正解決Servlet的線程安全問題,因為Servlet引擎會創(chuàng)建多個Servlet實例對象,而真正意義上解決多線程安全問題是指一個Servlet實例對象被多個線程同時調(diào)用的問題。因此大多數(shù)web是線程不安全的
六、與servlet相關(guān)的對象
1、ServletConfig對象
1.介紹
? ? ?當servlet配置了初始化參數(shù)后,web容器在創(chuàng)建servlet實例對象時,會自動將這些初始化參數(shù)封裝到ServletConfig對象中,并在調(diào)用servlet的init方法時,將ServletConfig對象傳遞給servlet。
2.servlet中配置初始化參數(shù)
<servlet><servlet-name>helloServlet</servlet-name><servlet-class>com.shen.HelloServlet</servlet-class><!-- 配置 Serlvet 的初始化參數(shù)。 且節(jié)點必須在 load-on-startup 節(jié)點的前面 --><init-param><!-- 參數(shù)名 --><param-name>user</param-name><!-- 參數(shù)值 --><param-value>root</param-value></init-param><init-param><param-name>password</param-name><param-value>1230</param-value></init-param><load-on-startup>-1</load-on-startup></servlet>?
3.獲取初始化參數(shù)
? ? ?從init方法中取出初始化參數(shù)
import java.io.IOException; import java.util.Enumeration;import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class ConfigServletDemo1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}@Overridepublic void init(ServletConfig config) throws ServletException {//獲取指定的初始化參數(shù)的值String value = config.getInitParameter("user");System.out.printfln(value)//打印出root//獲取所有的初始化參數(shù)Enumeration e = config.getInitParameterNames();//Enumeration是一個迭代器while(e.hasMoreElements()){String name = (String) e.nextElement();value = config.getInitParameter(name);System.out.printfln((name + "=" + value + "<br/>").getBytes());//打印出user root password 1230 }}}? ? ?然而事實上大部分都在doXXX方法中取出初始化參數(shù)故
public class ConfigServletDemo1 extends HttpServlet {private ServletConfig config;public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//獲取指定的初始化參數(shù)String value = config.getInitParameter("xxx");response.getOutputStream().write(value.getBytes());//獲取所有的初始化參數(shù)Enumeration e = config.getInitParameterNames();//Enumeration是一個迭代器while(e.hasMoreElements()){String name = (String) e.nextElement();value = config.getInitParameter(name);response.getOutputStream().write((name + "=" + value + "<br/>").getBytes());}}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}@Overridepublic void init(ServletConfig config) throws ServletException {this.config = config;}}? ? ?實際上在HttpServlet中重寫了init方法(HttpServler繼承于GenericServlet,GenericServlet重寫了該方法),即同上,故可以在doXXX方法中直接調(diào)用ServletConfig
public class ConfigServletDemo2 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {ServletConfig config = this.getServletConfig();System.out.println(config.getInitParameter("user"));//獲取指定的初始化參數(shù)String value = config.getInitParameter("user");response.getOutputStream().write(value.getBytes());}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}?
2、ServletContext對象
1.介紹
? ? ?WEB容器在啟動時,它會為每個WEB應(yīng)用程序都創(chuàng)建一個對應(yīng)的ServletContext對象,它代表當前web應(yīng)用。ServletConfig對象中維護了ServletContext對象的引用,開發(fā)人員在編寫servlet時,可以通過ServletConfig.getServletContext方法獲得ServletContext對象。由于一個WEB應(yīng)用中的所有Servlet共享同一個ServletContext對象,因此Servlet對象之間可以通過ServletContext對象來實現(xiàn)通訊。ServletContext對象通常也被稱之為context域?qū)ο蟆?/p>
2.servlet間數(shù)據(jù)共享
案例說明:有ServletDemo1,ServletDemo2,現(xiàn)ServletDemo1有數(shù)據(jù)data="shsj",將其共享給ServletDemo2。
//多個servlet通過servletContext實現(xiàn)數(shù)據(jù)共享 public class ServletDemo1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String data = "shsj";ServletContext context = this.getServletConfig().getServletContext();//一般不用該方法context.setAttribute("datasss", data); //map,將數(shù)據(jù)data放到關(guān)鍵字datasss中}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}} public class ServletDemo2 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {ServletContext context = this.getServletContext();String data = (String) context.getAttribute("datasss");//通過關(guān)鍵字獲取數(shù)據(jù)System.out.println(data);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}3.WEB應(yīng)用的初始化參數(shù)
1.全局初始化參數(shù)的配置
<context-param><param-name>url</param-name><param-value>jdbc:mysql://localhost:3306/test</param-value></context-param>?
2.全局初始化參數(shù)的獲取
//獲取整個web站點的初始化參數(shù) public class ServletContextDemo3 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {ServletContext context = this.getServletContext();String url = context.getInitParameter("url");System.out.println(url);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}4.實現(xiàn)Servlet的轉(zhuǎn)發(fā)
案例說明:有ServletDemo1,ServletDemo2,現(xiàn)ServletDemo1有請求,將其轉(zhuǎn)發(fā)給ServletDemo2處理。其中ServletDemo2的URL映射為/demo2
//用servletContext實現(xiàn)請求轉(zhuǎn)發(fā)public class ServletDemo1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {ServletContext context = this.getServletContext();RequestDispatcher rd = context.getRequestDispatcher("/demo2");rd.forward(request, response); //相當于調(diào)用ServletDemo2的doget(),故地址欄不變}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}} public class ServletDemo2 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.getOutputStream().write("servletDemo2來處理".getBytes());}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}分析:
如果ServletDemo1為:
//用servletContext實現(xiàn)請求轉(zhuǎn)發(fā) public class ServletDemo1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {ServletContext context = this.getServletContext();RequestDispatcher rd = context.getRequestDispatcher("/demo2");rd.forward(request, response); //相當于調(diào)用ServletDemo2的doget(),故地址欄不變System.out.println("我也執(zhí)行了");}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);} }"我也執(zhí)行了"將也會被打出,因為請求轉(zhuǎn)發(fā)僅僅相當于調(diào)用ServletDemo2的doGet方法,如果ServletDemo1為:
//用servletContext實現(xiàn)請求轉(zhuǎn)發(fā) public class ServletDemo1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {ServletContext context = this.getServletContext();RequestDispatcher rd = context.getRequestDispatcher("/demo2");rd.forward(request, response); //相當于調(diào)用ServletDemo2的doget(),故地址欄不變response.getOutputStream().write("111".getBytes());}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);} }"111"不會被瀏覽器顯示出來,因為response已經(jīng)被發(fā)出一次,不會再發(fā)出,如果ServletDemo1為:
//用servletContext實現(xiàn)請求轉(zhuǎn)發(fā) //注意: //1.轉(zhuǎn)發(fā)之前的所有寫入都無效 //2.轉(zhuǎn)發(fā)之前,response不能提交,否則轉(zhuǎn)發(fā)的時候服務(wù)器會拋:Cannot forward after response has been committed public class ServletDemo1 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.getOutputStream().write("111".getBytes());//轉(zhuǎn)發(fā)之前寫入,值被覆蓋/*OutputStream out=getOutputStream();response.out.write("111".getBytes());out.close //"111將會被寫出但報錯"*/ServletContext context = this.getServletContext();RequestDispatcher rd = context.getRequestDispatcher("/demo2");rd.forward(request, response); //相當于調(diào)用ServletDemo2的doget(),故地址欄不變}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);} }5.讀取資源文件
? ?有資源文件db.properties
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test username=root password=root1.資源文件在src目錄下
//使用servletContext讀取資源文件 public class ServleDemo extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {test2();}//做web工程時,不建議采用傳統(tǒng)方式讀取文件數(shù)據(jù)public void test1() throws FileNotFoundException {FileInputStream in = new FileInputStream("db.properties");//在tomcat服務(wù)器中將db.properties文件拷貝到E:\Tomcat8.5\bin后System.out.println(in);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}//讀取web工程中資源文件的模板代碼,一般就是這個private void test2() throws IOException {InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");//源文件在src目錄下Properties prop = new Properties();prop.load(in);String driver = prop.getProperty("driver");String url = prop.getProperty("url");String username = prop.getProperty("username");String password = prop.getProperty("password");System.out.println(driver);}//通過ServletContext獲取路徑后再采用傳統(tǒng)方式private void test3() throws IOException {//獲取web資源的絕對路徑String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");//在src目錄下FileInputStream in = new FileInputStream(path);Properties prop = new Properties();prop.load(in);String driver = prop.getProperty("driver");System.out.println(driver);}2.資源文件在src目錄下com.shen包下
private void test4() throws IOException {InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/shen/db.properties");//源文件在src目錄下Properties prop = new Properties();prop.load(in);String driver = prop.getProperty("driver");System.out.println(driver);}3.資源文件在webroot目錄下
private void test5() throws IOException {//讀取webroot目錄下的資源InputStream in = this.getServletContext().getResourceAsStream("/db.properties");//在webroot目錄下System.out.println(in);}4.用類裝載器讀取
? ? ?如果一個資源文件在src下(包括包下),更常用類裝載器來讀取
//用類裝載器讀取資源文件 public class ServletContextDemo extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {test1();}private void test1() throws IOException {ClassLoader loader = ServletContextDemo.class.getClassLoader();//獲取到裝載當前類的類裝載器InputStream in = loader.getResourceAsStream("db.properties");//用類裝載器裝載db.properties文件Properties prop = new Properties();prop.load(in);String driver = prop.getProperty("driver");System.out.println(driver);}//讀取類路徑下面、包下面的資源文件public void test2(){InputStream in = ServletContextDemo7.class.getClassLoader().getResourceAsStream("com/shen/db.properties");System.out.println(in);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}注意:
1.通過類裝載器讀取資源文件的注意事項:不適合裝載大文件,否則會導(dǎo)致jvm內(nèi)存溢出
//通過類裝載器讀取資源文件的注意事項:不適合裝載大文件,否則會導(dǎo)致jvm內(nèi)存溢出public void test3(){InputStream in = ServletContextDemo7.class.getClassLoader().getResourceAsStream("PranavMistry_2009I_480.mp4");//如讀取一個電影System.out.println(in);}//文件太大,只能用servletContextpublic void test4() throws IOException{//讀取PranavMistry_2009I_480.mp4,并拷貝到e:\根目錄下//path=c:\asdf\adsd\add\PranavMistry_2009I_480.mp4//path=PranavMistry_2009I_480.mp4獲取文件名String path = this.getServletContext().getRealPath("/WEB-INF/classes/PranavMistry_2009I_480.mp4");String filename = path.substring(path.lastIndexOf("\\")+1);//截取到文件名【lastIndexOf("\\")+1表示截取到字符串中最后一個'\'字符后的部分】//將該文件輸入到內(nèi)存(之前在web服務(wù)器)InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/PranavMistry_2009I_480.mp4");byte buffer[] = new byte[1024];int len = 0;//將該文件寫入到硬盤FileOutputStream out = new FileOutputStream("e:\\" + filename);while((len=in.read(buffer))>0){out.write(buffer,0,len);}out.close();in.close();}2.如果是一個普通的類,因為沒有ServletContext對象故只能通過類的裝載方法進行數(shù)據(jù)的讀取,Dao.java,通過ServletDemo調(diào)用
public class ServletDemo extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Dao dao = new Dao();dao.run();}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}dao.java
public class Dao {//讀取資源文件,并更新資源文件public void run() throws IOException{URL url = this.getClass().getClassLoader().getResource("db.properties");String path = url.getPath();FileInputStream in = new FileInputStream(path);//讀取數(shù)據(jù)FileOutputStream out = new FileOutputStream(path);//寫入數(shù)據(jù)Properties prop = new Properties();prop.load(in);System.out.println(prop.size());prop.setProperty("name", "flx");prop.store(out, "");}}?
總結(jié)
以上是生活随笔為你收集整理的Java web开发——Servlet详细介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【剑桥英语I优加】剑桥pet考试适合多大
- 下一篇: Java 创建事件Event、事件监听E