一、servletConfig對(duì)象
在Servlet的配置文件中厉亏,可以使用一個(gè)或多個(gè)<init-param>標(biāo)簽為servlet配置一些初始化參數(shù)。比如:
<servlet>
<servlet-name>ConfigDemo1</servlet-name>
<servlet-class>cn.itcast.servletConfig.ConfigDemo1 </servlet-class>
<init-param>
<param-name>xxx</param-name>
<param-value>123</param-value>
</init-param>
</servlet>
注意:針對(duì)每個(gè)servlet,我們需要為其單獨(dú)配置饭耳,而在servlet元素外面使用標(biāo)簽<context-param>配置的初始化信息是對(duì)所有的servlet共享的。
現(xiàn)在我們?cè)趕ervlet中使用初始化信息(工程ConfigAndContext):
packagecn.itcast.servletConfig;
importjava.io.IOException;
importjavax.servlet.ServletConfig;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
public class ConfigDemo1 extends HttpServlet{
private ServletConfig config;
public void init(ServletConfig config)throws ServletException{
String value=config.getInitParameter("xxx");
System.out.println(value);
}
public void doGet(HttpServletRequestrequest, HttpServletResponseresponse)
throws ServletException,IOException{
}
public void doPost(HttpServletRequestrequest, HttpServletResponseresponse)
throws ServletException,IOException{
doGet(request,response);
}
}
當(dāng)我們使用地址 http://localhost:8080/ConfigAndContext/servlet/ConfigDemo1 訪問時(shí)在窗口中會(huì)打印出123這個(gè)初始化信息执解。我們也可以在doGet方法中使用:
package cn.itcast.servletConfig;
import java.io.IOException;
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 ConfigDemo1 extends HttpServlet {
private ServletConfig config;
public void init(ServletConfig config) throws ServletException{
//在初始化方法中使用
/*String value = config.getInitParameter("xxx");
System.out.println(value);*/
this.config = config;//在doGet方法中使用
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到初始化參數(shù)
String value = config.getInitParameter("xxx");
//會(huì)將得到的初始化參數(shù)打印在網(wǎng)頁中,注意輸出方式
response.getOutputStream().write(value.getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
當(dāng)然我們也可以配置多個(gè)初始化參數(shù)寞肖,并通過名字得到相關(guān)的值:
package cn.itcast.servletConfig;
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 ConfigDemo1 extends HttpServlet {
private ServletConfig config;
public void init(ServletConfig config) throws ServletException{
//在初始化方法中使用
/*String value = config.getInitParameter("xxx");
System.out.println(value);*/
this.config = config;//在doGet方法中使用
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到初始化參數(shù)
String value = config.getInitParameter("xxx");
//會(huì)將得到的初始化參數(shù)打印在網(wǎng)頁中,注意輸出方式
response.getOutputStream().write(value.getBytes());
//得到多個(gè)初始化參數(shù)
Enumeration e = config.getInitParameterNames();
while(e.hasMoreElements()){
String name = (String) e.nextElement();
value = config.getInitParameter(name);
response.getOutputStream().write((name + "=" + value).getBytes());
}
//得到碼表
String charset = this.config.getInitParameter("charset");
//得到鏈接數(shù)據(jù)庫
String url = this.config.getInitParameter("url");
String username = this.config.getInitParameter("username");
String password = this.config.getInitParameter("password");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
其配置信息如下:
<servlet>
<servlet-name>ConfigDemo1</servlet-name>
<servlet-class>cn.itcast.servletConfig.ConfigDemo1</servlet-class>
<init-param>
<param-name>xxx</param-name>
<param-value>yyy</param-value>
</init-param>
<init-param><!--配置碼表-->
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!--配置數(shù)據(jù)庫-->
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://3305/test</param-value>
</init-param>
<init-param><!--配置用戶名-->
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param><!--配置密碼-->
<param-name>password</param-name>
<param-value>walp1314</param-value>
</init-param>
</servlet>
當(dāng)servlet配置了初始化參數(shù)后,web容器在創(chuàng)建servlet實(shí)例對(duì)象時(shí)材鹦,會(huì)自動(dòng)將這些初始化參數(shù)封裝到ServletConfig對(duì)象中逝淹,并在調(diào)用servlet的init方法時(shí),將ServletConfig對(duì)象就可以得到當(dāng)前servlet的初始化參數(shù)信息桶唐。也就是說我們不需要自己定義一個(gè)ServletConfig字段栅葡,直接使用即可。
package cn.itcast.servletConfig;
import java.io.IOException;
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 ConfigDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//我們直接得到ServletConfig對(duì)象
ServletConfig config = this.getServletConfig();
System.out.println("aaa" + config.getInitParameter("xx"));
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
二尤泽、ServletContext對(duì)象(context域?qū)ο螅?/h1>
(1)ServletConfig對(duì)象中維護(hù)了ServletContext對(duì)象的引用欣簇,開發(fā)人員在編寫servlet時(shí),可以通過ServletConfig.getServletContext方法獲得ServletContext對(duì)象坯约。 然后從context域中取出我們存入的數(shù)據(jù): web容器在啟動(dòng)時(shí)横殴,它會(huì)為每個(gè)web應(yīng)用程序都創(chuàng)建一個(gè)對(duì)應(yīng)的ServletContext對(duì)象,它代表當(dāng)前的web應(yīng)用。即ServletContext對(duì)象可以對(duì)整個(gè)web應(yīng)用中所有的servlet使用衫仑,同時(shí)一般不在其中一個(gè)<servlet>標(biāo)簽中定義梨与,而是在外部定義。如: 這里我們通過context對(duì)象獲得整個(gè)站點(diǎn)的初始化資源: 我們?cè)L問ContextDemo4這個(gè)servlet等浊,然后這個(gè)servlet將請(qǐng)求轉(zhuǎn)發(fā)給ContextDemo5進(jìn)行處理: 注意上面四種特殊情況。 ContextDemo5進(jìn)行處理轉(zhuǎn)發(fā)的請(qǐng)求: 在web工程中我們用到資源文件時(shí)一般就是.xml文件或者.properties文件兼犯,一般較為復(fù)雜的資源文件使用.xml忍捡,簡單文件使用.properties文件。 資源文件(db1.properties) 下面看操作資源文件: 注意:這里的test1方法中我們采用傳統(tǒng)的方式去讀取資源文件切黔。但是如果這樣讀取資源文件我們將資源文件放在工程中的任何目錄都是訪問不了的砸脊,因?yàn)檫@個(gè)程序是右tomcat去調(diào)用java虛擬機(jī)執(zhí)行,所以我們?nèi)绻麑①Y源文件放在工程中纬霞,那么路徑就要寫這個(gè)資源文件路徑(如果是在src下凌埂,那么路徑就是classes)相對(duì)于tomcat的bin目錄的地址。這顯然很麻煩诗芜,當(dāng)然我們也可以將資源文件直接放在tomcat的bin目錄中瞳抓,此時(shí)直接寫上文件名即可,但是這在實(shí)際開發(fā)中顯然是行不通的伏恐。 方式二:使用ServletContext對(duì)象讀取資源文件(1) 方式三:使用ServletContext對(duì)象讀取資源文件(2) 方式四:讀取WebRoot目錄下的資源文件 下面看使用類裝載器讀取資源文件(一定要注意:雖然都放在src目錄下,但是路徑寫法不同) 說明:這里之所以不使用getResourceAsStream方法是因?yàn)槿绻@樣那么第一次訪問時(shí)類裝載器就會(huì)將資源文件加載進(jìn)去渠羞,但是如果我們想程序后面那樣對(duì)文件進(jìn)行寫入操作后斤贰,之后的訪問還是不會(huì)得到相關(guān)的值,和上面不同次询,上面只是第一次沒有值荧恍,但是之后就會(huì)有值。這是因?yàn)轭惣虞d器在每次加載的時(shí)候會(huì)先看內(nèi)存中是否有這個(gè)資源文件屯吊,如果有就不會(huì)再次加載送巡,所以如果使用getResourceAsStream方法,那么我們每次訪問的資源文件都是第一次加載的那個(gè)盒卸,而不會(huì)更新骗爆。除非關(guān)掉web服務(wù)器,這顯然不現(xiàn)實(shí)蔽介。但是我們通過其路徑每次都new一個(gè)輸入輸出流則會(huì)每次都去更新資源文件摘投。 注意:這里我們?cè)谠囼?yàn)時(shí)可以在Internet選項(xiàng)中常規(guī)-設(shè)置-查看文件里面可以查看到緩存的文件虹蓄,同時(shí)我們不能使用刷新查看試驗(yàn)結(jié)果犀呼,因?yàn)橹灰撬⑿露紩?huì)想服務(wù)器請(qǐng)求數(shù)據(jù),所以這里我們可以使用超鏈接進(jìn)行試驗(yàn)薇组。
(2)由于一個(gè)web應(yīng)用中的所有servlet共享同一個(gè)ServletContext對(duì)象熊咽,因此servlet對(duì)象之間可以通過ServletContext對(duì)象來實(shí)現(xiàn)通訊,ServletContext對(duì)象通常也被稱之為context域?qū)ο?/strong>闹丐。
我們先將數(shù)據(jù)通過servlet存入context域?qū)ο笾校?/p>
package cn.itcast.context;
//多個(gè)servlet通過servletContext實(shí)現(xiàn)數(shù)據(jù)共享
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//將數(shù)據(jù)存到context對(duì)象之中
public class ContextDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String data = "aaa";
ServletContext context = this.getServletConfig().getServletContext();
context.setAttribute("data", data);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package cn.itcast.servletConfig;
import java.io.IOException;
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 ConfigDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//我們直接得到ServletConfig對(duì)象
ServletConfig config = this.getServletConfig();
System.out.println("aaa" + config.getInitParameter("xx"));
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
<web-app>
<context-param>
<param-name>1111</param-name>
<param-value>2222</param-value>
</context-param>
文狱。粥鞋。。瞄崇。呻粹。。
package cn.itcast.context;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ContextDemo3 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//注意:這里我們其實(shí)可以直接取得context對(duì)象苏研,而不需要通過ServletConfig對(duì)象
ServletContext context = this.getServletContext();
String name = context.getInitParameter("1111");
System.out.println(name);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
實(shí)現(xiàn)servlet之間的轉(zhuǎn)發(fā)
package cn.itcast.context;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ContextDemo4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.注意:字符串是不會(huì)在瀏覽器中輸出的,因?yàn)槲覀冊(cè)谵D(zhuǎn)發(fā)后楣富,ContextDemo5這個(gè)
//servlet會(huì)將response中的數(shù)據(jù)全部清掉
response.getOutputStream().write("1111".getBytes());
//2.這種情況我們強(qiáng)制關(guān)閉流會(huì)自動(dòng)清理緩存凿掂,也就是說會(huì)將字符串輸出到瀏覽器中
//但是此時(shí)轉(zhuǎn)發(fā)請(qǐng)求會(huì)出錯(cuò),因?yàn)榱饕呀?jīng)關(guān)閉了.
OutputStream out = response.getOutputStream();
out.write("1111".getBytes());
out.close();
ServletContext context = this.getServletContext();
RequestDispatcher rd = context.getRequestDispatcher("/servlet/ContextDemo5");
rd.forward(request, response);
//3.這行代碼是會(huì)執(zhí)行的纹蝴,會(huì)在窗口打印出字符串
System.out.println("Hello");
//4.這行代碼雖然會(huì)執(zhí)行庄萎,但是不會(huì)發(fā)到瀏覽器中,因?yàn)榇藭r(shí)在請(qǐng)求轉(zhuǎn)發(fā)之后相當(dāng)于
//整個(gè)操作已經(jīng)結(jié)束了塘安,數(shù)據(jù)就不會(huì)發(fā)送到瀏覽器中了糠涛。
response.getOutputStream().write("Hello".getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package cn.itcast.context;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ContextDemo5 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getOutputStream().write("ContextDemo5".getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3305/test
username=root
password=walp1314
package cn.itcast.context;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ContextDemo6 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
test1();
}catch(Exception e){
e.printStackTrace();
}
}
//使用傳統(tǒng)方式讀取資源文件
public void test1() throws Exception{
FileInputStream fin = new FileInputStream("db1.properties");
System.out.println(fin);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
//使用ServletContext對(duì)象讀取資源文件(1)
public void test2() throws Exception{
//此時(shí)我們將配置文件放在src下孩哑,部署之后此文件在/WEB-INF/classes下。
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db1.properties");
//讀取properties文件需要使用Properties對(duì)象
Properties properties = new Properties();
properties.load(in);
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driver);
}
//使用ServletContext對(duì)象讀取資源文件(2)
public void test3() throws IOException{
//這里我們得到資源文件的絕對(duì)路徑翠桦,此時(shí)資源文件放在src下
String path = this.getServletContext().getRealPath("/WEB-INF/classes/db1.properties");
//之后就可以采用傳統(tǒng)方式進(jìn)行讀取
FileInputStream fin = new FileInputStream(path);
Properties properties = new Properties();
properties.load(fin);
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driver);
}
//讀取WebRoot目錄下的資源文件
public void test4() throws IOException{
//注意此時(shí)資源文件是在webRoot下的横蜒,也就是在web工程下面,可以直接讀取
InputStream in = this.getServletContext().getResourceAsStream("/db2.properties");
Properties properties = new Properties();
properties.load(in);
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driver);
}
package cn.itcast.context;
//使用類裝載器讀取資源文件
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ContextDemo7 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
test1();
}catch(Exception e){
e.printStackTrace();
}
}
public void test1() throws IOException{
ClassLoader loader = ContextDemo7.class.getClassLoader();
//注意:這里的資源文件也是放在src目錄下面丛晌,但是和之前的寫法卻不同
InputStream in = loader.getResourceAsStream("db1.properties");
//說明:這個(gè)類裝載器裝載src下的class文件鹰霍,當(dāng)然也可以裝載資源文件,而資源文件剛好
//在src下茵乱,所有資源文件和類裝載器在同一個(gè)目錄中
Properties properties = new Properties();
properties.load(in);
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driver);
}
//讀取類路徑下(包下)的資源文件
public void test2() throws IOException{
ClassLoader loader = ContextDemo7.class.getClassLoader();
InputStream in = loader.getResourceAsStream("cn/itcast/context/db1.properties");
Properties properties = new Properties();
properties.load(in);
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(driver);
}
//但是通過類裝載器讀取資源文件在資源文件很大的時(shí)候容易造成虛擬機(jī)內(nèi)存溢出
//所以使用類裝載器的方式不適合讀取較大的資源文件
//下面讀取較大的資源文件
public void test3() throws IOException{
//讀取db.mp4并拷貝到E:\根目錄下
//path路徑有兩種情況:1.path=C:\aaa\bbb\db.mp4; 2.path=db.mp4
String path = this.getServletContext().getRealPath("WEB-INF/classes/db.mp4");
//資源文件放在src下,這里我們是需要從路徑中截取出文件名
String filename = path.substring(path.lastIndexOf("\\") + 1);
//這里表示從最后一個(gè)\的后面一個(gè)字符開始截取
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.mp4");
byte buffer[] = new byte[1024];//開辟一個(gè)緩沖區(qū)
int len = 0;
FileOutputStream out = new FileOutputStream("e:\\" + filename);
while((len = in.read(buffer)) > 0){
out.write(buffer, 0, len);
}
out.close();
in.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
普通java類通過servlet讀取資源文件
package cn.itcast.dao;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
//在普通java類中取得(或?qū)懭耄┵Y源文件中的相關(guān)數(shù)據(jù)只能功過類裝載器來實(shí)現(xiàn)
public class Dao {
public void run() throws IOException{
//這里資源文件在src下孟岛,注意:這里不能使用getResourceAsStream方法瓶竭,原因在后面說明
URL url_s = Dao.class.getClassLoader().getResource("db1.properties");
//結(jié)果是file:/E:/apache/tomcat/tomcat/webapps/ConfigAndContext/WEB-INF/classes/db1.properties
//System.out.println(url_s);
//得到資源的絕對(duì)路徑
String path = url_s.getPath();
//結(jié)果是/E:/apache/tomcat/tomcat/webapps/ConfigAndContext/WEB-INF/classes/db1.properties
//System.out.println(path);
FileInputStream in = new FileInputStream(path);
//注意:new一個(gè)FileOutputStream時(shí)如果不設(shè)置布爾值就會(huì)將文件清空
FileOutputStream out = new FileOutputStream(path, true);
Properties properties = new Properties();
properties.load(in);
System.out.println(properties.getProperty("driver"));
System.out.println(properties.getProperty("url"));
System.out.println(properties.getProperty("username"));
System.out.println(properties.getProperty("password"));
//第一次訪問的時(shí)候值是null,第二次才會(huì)有值
System.out.println(properties.getProperty("name"));
properties.setProperty("name", "yj");
//將相關(guān)內(nèi)容寫入到文件中去
properties.store(out, "");
}
}
package cn.itcast.context;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.dao.Dao;
public class ContextDemo8 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);
}
}
緩存一些不經(jīng)常變化的資源到瀏覽器中,提升服務(wù)器性能
package cn.itcast.context;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ContextDemo9 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String data = "aaa";
//緩存一天
response.setDateHeader("expires", System.currentTimeMillis() + 24*3600*1000);
response.getOutputStream().write(data.getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}