ServletContext 代表整個(gè)Web應(yīng)用漾稀。
- Web應(yīng)用中所有的Servlet 共享一個(gè)ServletContext∷H粒可以最為Servlet之間通信的橋梁武通。
- 獲取Web應(yīng)用的初始化參數(shù)
- 可以通過它來得到該Web工程所有的資源。
- 實(shí)現(xiàn)Servlet的轉(zhuǎn)發(fā)
實(shí)現(xiàn) Web工程下的 所有的Servlet 數(shù)據(jù)共享
public class ServletContextDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//將數(shù)據(jù)通過 ServletContext 傳遞給 其他的 Servlet
String data="基本密碼";
ServletContext servletContext=this.getServletContext() ;
servletContext.setAttribute("ServletContext的數(shù)據(jù)", data); //內(nèi)部 是以 Map的形式實(shí)現(xiàn)的
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
另一個(gè)Servlet 得到ServletContextDemo1 所的共享的數(shù)據(jù)
public class ServletContextDemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//得到 其他的Servlet 共享的數(shù)據(jù)
ServletContext servletContext=this.getServletContext();
String data=(String) servletContext.getAttribute("ServletContext的數(shù)據(jù)");
response.getOutputStream().write(data.getBytes());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
獲取Web應(yīng)用的初始化參數(shù)(整個(gè)web站點(diǎn)的參數(shù) 不止對(duì)應(yīng)一個(gè)Servlet)
<context-param>
<param-name>xxx</param-name>
<param-value>yyy</param-value>
</context-param>
//獲取整個(gè)站點(diǎn)下的 初始化參數(shù)信息
ServletContext servletContext=this.getServletContext() ;
String value=servletContext.getInitParameter("xxx");
實(shí)現(xiàn)Servlet的轉(zhuǎn)發(fā)
當(dāng)一個(gè)Servlet收到請(qǐng)求后计螺,將此請(qǐng)求重定向給其他的Servelt去夯尽。讓其他的Servlet去處理
public class ServletContextDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext s=this.getServletContext();
//收到請(qǐng)求后進(jìn)行轉(zhuǎn)發(fā)到 ServletContextDemo2中去
ServletContext s=this.getServletContext();
//次個(gè)操作無效 因?yàn)楹竺嬗修D(zhuǎn)發(fā)的操作,轉(zhuǎn)發(fā)操作的時(shí)候會(huì)把 response中清空 登馒。在轉(zhuǎn)發(fā)前的所有寫入無效匙握。2.在轉(zhuǎn)發(fā)前不能提交,否服務(wù)器會(huì)報(bào)異常陈轿。
response.getOutputStream().write("這個(gè)是ServletContextDemo1過來的數(shù)據(jù)哦".getBytes());
RequestDispatcher requestDispatcher= s.getRequestDispatcher("/ServletContextDemo2");
requestDispatcher.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
public class ServletContextDemo2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getOutputStream().write("這個(gè)是ServletContextDemo1過來的數(shù)據(jù)哦".getBytes());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
當(dāng)ServletContextDemo1 收到請(qǐng)求后轉(zhuǎn)發(fā)給ServletContextDemo2 處理圈纺。
一般Servlet 當(dāng)服務(wù)器得到請(qǐng)求后,要將 排版后(HTML格式)的數(shù)據(jù)交給瀏覽器處理麦射,但是Servlet并不適合排版的處理蛾娶,通常是轉(zhuǎn)發(fā)給 JSP進(jìn)行處理。
/**
* 請(qǐng)求的轉(zhuǎn)發(fā) 給jsp
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String data="jibenmima";
this.getServletContext().setAttribute("name", data);
RequestDispatcher r =request.getRequestDispatcher("/JspDemo1.jsp");
//請(qǐng)求轉(zhuǎn)發(fā)的第兩種方式 沒有區(qū)別
// RequestDispatcher r = this.getServletContext().getRequestDispatcher("/JspDemo1.jsp");
r.forward(request, response);
//當(dāng)要給jsp傳遞數(shù)據(jù)的時(shí)候 千萬不能用上面的方式 潜秋。用 ServletContext來存放數(shù)據(jù)蛔琅,然后再根據(jù)ServletContext來獲取。
//這樣有線程安全的問題峻呛。因?yàn)樗械脑L問都是用的同一個(gè) ServletContext 后面的可能會(huì)把之前的覆蓋掉
//所有這個(gè)時(shí)候就要用到 request.setAttribute(name, o); 這個(gè)方法了罗售。request 是作為一個(gè)域容器辜窑,將數(shù)據(jù)存放到域容器中,在jsp等 獲取就行
String data="jibenmima";
request.setAttribute("name", data);
RequestDispatcher r =request.getRequestDispatcher("/JspDemo1.jsp");
r.forward(request, response);
System.out.println(data);
}
下面是jsp的代碼 jsp自認(rèn)為就是可以寫java代碼的html
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
String name=(String)this.getServletContext().getAttribute("name");
out.write(name);
//要用此方式來進(jìn)行接收數(shù)據(jù) 不要用上面的
String name=(String) request.getAttribute("name");
out.write(name);
%>
</body>
</html>
可以通過它來得到該Web工程所有的資源
首先在src下面創(chuàng)建 db.properties 用來保持?jǐn)?shù)據(jù)庫(kù)的配置信息
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root
通過流來讀取此文件莽囤,注意這里有個(gè)文件的路徑問題谬擦。因?yàn)槲覀兪菍⒊绦虬l(fā)布到Tomcat中的webapps中去,在啟動(dòng)程序的時(shí)候朽缎,相當(dāng)于啟動(dòng)了bin中的startup.bat惨远。相當(dāng)于這個(gè)文件是相對(duì)于bin文件的路徑來調(diào)用的。我們把db.properties文件復(fù)制一份到bin文件中话肖,直接調(diào)用
FileOutputStream fileOutputStream=new FileOutputStream("db.properties");
System.out.println(fileOutputStream);
沒問題的北秽。這個(gè)目錄(bin)相當(dāng)于java虛擬機(jī)的啟動(dòng)目錄。但是這個(gè)方式很惡心最筒。不建議使用贺氓。
既然這個(gè)ServletContext代表整個(gè)web資源,那么它肯定有方法來獲取整個(gè)web資源的方法床蜘。
下面是代碼
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//當(dāng) src下有資源的話
// getServletContext代表整個(gè)Web應(yīng)用辙培。
// 而這個(gè) db.properties 發(fā)布后的路徑是
// D:\tomcat\apache-tomcat-8.5.8\wtpwebapps\Day052\WEB-INF\classes
// 所以這個(gè) dbpath 為下面路徑
String dbPath = "/WEB-INF/classes/db.properties";
InputStream inputStream = getServletContext().getResourceAsStream(dbPath);
//讀取 db.properties 中的數(shù)據(jù)
Properties properties = new Properties();
properties.load(inputStream);
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
//當(dāng)然你也可以用 getRealPath 方法來獲取資源的絕對(duì)路徑
String path=getServletContext().getRealPath("/WEB-INF/classes/db.properties");
FileOutputStream fileOutputStream=new FileOutputStream(path);
//下面是模板代碼進(jìn)行讀取 內(nèi)容
//當(dāng) scr下面有資源的話 可以用類加載器進(jìn)行加載資源
//但是類加載器有問題。當(dāng)資源文件過大的時(shí)候邢锯,或?qū)е绿摂M機(jī)崩潰 內(nèi)存溢出(不建議使用)
//因?yàn)?在目錄下面生成的.class文件需要有類的加載器來調(diào)用 java類扬蕊,那么也能調(diào)用 該目錄下面的資源
ClassLoader servletContextLoader = ServletContextDemo2.class.getClassLoader();//得到類的加載器
InputStream inputStream2=servletContextLoader.getResourceAsStream("db.properties");
//下面是模板代碼進(jìn)行讀取 內(nèi)容
//當(dāng)項(xiàng)目下有資源的話,D:\tomcat\apache-tomcat-8.5.8\wtpwebapps\Day052
InputStream inputStreamRoot = getServletContext().getResourceAsStream("/dba.properties");
}
讀取 src下面的文件到 e盤下song文件夾下
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// test1();
//讀取 src下面的文件 復(fù)制到 D盤中song的文件夾下
//1丹擎、 獲取此文件的絕對(duì)路徑以便能截取它的名字尾抑,方便后邊給它賦名字
String path=this.getServletContext().getRealPath("/WEB-INF/classes/movie.avi");
System.out.println(path);//打印為:D:\tomcat\apache-tomcat-8.5.8\wtpwebapps\Day052\WEB-INF\classes\movie.avi
//根據(jù)路徑來得到 文件的名字
String pathName=path.substring(path.lastIndexOf("\\")+1);
FileInputStream fileInputStream=new FileInputStream(path);
//模板代碼
byte[] buffer=new byte[1024];
int len=0;
FileOutputStream fileOutputStream=new FileOutputStream("e://song//"+pathName);
while((len=fileInputStream.read(buffer))>0)
{
fileOutputStream.write(buffer,0,len);
}
fileOutputStream.close();
fileInputStream.close();
response.getWriter().write("成功");
}
當(dāng)沒有ServletContext時(shí),用類加載器來加載資源蒂培。下面的代碼包含了流的操作和properties的讀和寫
public class Dao {
// 文件的 工具類 用來讀取 信息再愈,比如 db.properties
//當(dāng)讀取src下面的文件的時(shí)候,必須使用 類加載器了 因?yàn)檫@里沒有ServletContext對(duì)象的實(shí)例
public void getInfo(){
try {
//這里必須使用 Dao.class.getClassLoader().getResource()方法护戳。
//因?yàn)?當(dāng)如果用 getResourceAsStream(name)時(shí)翎冲,返回的是一個(gè) inputStream。當(dāng)類加載的時(shí)候只會(huì)加載一次媳荒。
//當(dāng)你向里面重新寫數(shù)據(jù)后抗悍,次 流中 的數(shù)據(jù)不變化。 所有要使用 返回 絕對(duì)路徑的方法肺樟。
URL url= Dao.class.getClassLoader().getResource("db.properties");
String path=url.getPath();
FileInputStream fileInputStream=new FileInputStream(path);
Properties properties=new Properties();
properties.load(fileInputStream);
String propertiesUrl=properties.getProperty("url");
properties.setProperty("name", "value");
//注意此方法的位置檐春。當(dāng)你new FileOutputStream(path)的時(shí)候逻淌,它會(huì)默認(rèn)將里面的數(shù)據(jù)清空么伯。一定要等到
//properties.load(fileInputStream); 后再進(jìn)行new 次對(duì)象
FileOutputStream outputStream=new FileOutputStream(path);
//將數(shù)據(jù) 刷新到流中
properties.store(outputStream, "");
} catch (Exception e) {
e.printStackTrace();
}
}