心得5--ServletContext及一些细节
1. 学习java就有面向对象的思想,拿到一个对象不要去刻意去想这个对象有什么方法,是什么作用。而要用面向对象的思想去考虑,再想改对象有什么方法。比如:拿到一个学生对象,你会想到该对象有学习的方法;拿到一个狗对象,你会想到该对象有咬人、啃骨头的方法,拿到一个web对象,你应该想到有数据共享的方法,ServletContext就代表一个web应用。
2. java中有四个域,域就是范围的意思。这四个域分别为:request、session、page、context。Context域对象作用的范围是整个应用的范围,只要应用不退出,谁都可以访问。
3.ServletContext
• WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
• ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
也可以使用 this.getServletContext方法
例子:
//获取ServletContext的两种方式:
//方法一:通过ServletConfig获取
ServletContext sc1 = this.getServletConfig().getServletContext();
//方法二:通过servlet类直接获取
ServletContext sc2 = this.getServletContext();
• 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。多个Servlet通过ServletContext对象实现数据共享。
• ServletContext对象通常也被称之为context域对象。(request,session,page)
setAttribute(),getAttribute();
例子:
/*
ServletContext域:
这是一个容器
ServetContext域这句话说明了这个容器作用范围,也就是应用程序范围
通过ServletContext实现ContextDemo2和ContextDemo3的数据共享
*/
ContextDemo2.java
package com.context;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
public class ContextDemo2 extends HttpServlet{
publicvoid doGet(HttpServletRequest request, HttpServletResponse response)
throwsServletException, IOException {
Stringdata = "aaaa";
this.getServletContext().setAttribute("data",data);
}
publicvoid doPost(HttpServletRequest request, HttpServletResponse response)
throwsServletException, IOException {
doGet(request,response);
}
}
ContextDemo3.java
package com.context;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
public class ContextDemo3 extends HttpServlet{
publicvoid doGet(HttpServletRequest request, HttpServletResponse response)
throwsServletException, IOException {
System.out.println(this.getServletContext().getAttribute("data"));
}
publicvoid doPost(HttpServletRequest request, HttpServletResponse response)
throwsServletException, IOException {
doGet(request,response);
}
}
4.ServletContext应用
• 获取WEB应用的初始化参数。
<context-param>
<param-name>data</param-name>
<param-value>xxxx</param-value>
</context-param>
例子:
Web.xml中的配置信息:
<context-param>
<param-name>data1</param-name>
<param-value>zzzz</param-value>
</context-param>
<context-param>
<param-name>data2</param-name>
<param-value>xxxxx</param-value>
</context-param>
<context-param>
<param-name>data3</param-name>
<param-value>qqqqq</param-value>
</context-param>
ContextDemo4.Java
package com.context;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
//获得web应用的初始化参数
public class ContextDemo4 extends HttpServlet{
publicvoid doGet(HttpServletRequest request, HttpServletResponse response)
throwsServletException, IOException {
//输出一条初始化信息
System.out.println(this.getServletContext().getInitParameter("data1"));
//输出多条初始化信息
Enumerationen = this.getServletContext().getInitParameterNames();
while(en.hasMoreElements()){
Stringname = (String) en.nextElement();
Stringvalue = this.getServletConfig().getServletContext().getInitParameter(name);
// 这里与前面有点不同,这里是获取Context对象来获取initparameter方法的
System.out.println(name+"---"+value);
}
}
publicvoid doPost(HttpServletRequest request, HttpServletResponse response)
throwsServletException, IOException {
doGet(request,response);
}
}
• 实现Servlet的转发。
转发就是你向我借钱,我没有我替你向别人借。重定向是你向我借钱我没有,我让你向别人借。
如果用到html设置文件,却不使用转发,怎会出现下面这种情况:response.getOutputStream().write(("<font color='red'>"+value+"</font>").getBytes());
RequestDispatcher rd =getServletContext().getRequestDispatcher(“/1.jsp”);
rd.forward(request,response);
Jsp就是一个可以写java代码的html。
如何把数据传到 1.jsp ?(可以通过request域,不能用context域)
例子:
Lsp中代码:
<h1>
<font color=“blue”>
<%
String data =(String)application.getAttribute("data");
out.write(data);
%>
</font>
</h1>
ContextDemo5.java
package com.context;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//通过SevletCondext实现转发
public class ContextDemo5 extends HttpServlet{
publicvoid doGet(HttpServletRequest request, HttpServletResponse response)
throwsServletException, IOException {
Stringdata = "dhflk";
this.getServletContext().setAttribute("data",data);
//把数据带给index.jsp
RequestDispatcherrd = this.getServletContext().getRequestDispatcher("/1.jsp");
rd.forward(request,response);
}
publicvoid doPost(HttpServletRequest request, HttpServletResponse response)
throwsServletException, IOException {
doGet(request,response);
}
}
• 利用ServletContext对象读取资源文件。
软件开发中用的配置文件大概有两种:xml和properties。这两个配置文件的区别是:xml文件里的数据是有关系的,而后者没有。
– 得到文件路径
– 读取资源文件的三种方式
.properties文件(属性文件)
例子:
package com.context;
import java.io.FileInputStream;
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;
publicclass ContextDemo6 extends HttpServlet {
publicvoid doGet(HttpServletRequest request, HttpServletResponseresponse)
throws ServletException, IOException {
test5();
}
//正常情况下,即db.properties在src路径下的情况
publicvoid test1() throws IOException {
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties pro = new Properties();
pro.load(in);
String driver = pro.getProperty("driver");
String url = pro.getProperty("url");
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println(driver);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}
//db.properties在包路下的情况
publicvoid test2() throws IOException {
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/context/db.properties");
Properties pro = new Properties();
pro.load(in);
String driver = pro.getProperty("driver");
String url = pro.getProperty("url");
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println(driver);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}
//db.properties在跟目录下,即WebRoot下或者以上情况都可以这么写的情况
publicvoid test3() throws IOException {
InputStream in = this.getServletContext().getResourceAsStream("/db.properties");
Properties pro = new Properties();
pro.load(in);
String driver = pro.getProperty("driver");
String url = pro.getProperty("url");
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println(driver);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}
//两种种错误的情况:系统找不到指定的路径,服务器端错误,找不到指定文件
publicvoid test4() throws IOException {
FileInputStream in = new FileInputStream("src/db.properties");
/*改成这个也不对:FileInputStream in = newFileInputStream("classes/db.properties");
虽然web项目下有这个目录.这行代码由tomcat服务器调用,服务器由jdk调用,相对路径是相对于java虚拟机的目录,java虚拟机是在tomcat服务器启动时启动的,
所以相对路径是tomcat服务器的bin路径*/
Properties pro = new Properties();
pro.load(in);
String driver = pro.getProperty("driver");
String url = pro.getProperty("url");
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println(driver);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}
//通过ServletContext的getRealPath()方法得到资源的绝对路径后,再通过传统流读取资源文件
//改方法既可获取数据又获取名称;前面的几种方法只能获取数据
publicvoid test5() throws IOException {
String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
String filename = path.substring(path.lastIndexOf("\\")+1);
System.out.println("当前读取到的资源名称是:"+filename);
FileInputStream in = new FileInputStream(path);
Properties pro = new Properties();
pro.load(in);
String driver = pro.getProperty("driver");
String url = pro.getProperty("url");
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println("当前读取到的资源数据是:");
System.out.println(driver);
System.out.println(url);
System.out.println(username);
System.out.println(password);
}
publicvoid doPost(HttpServletRequest request, HttpServletResponseresponse)
throws ServletException, IOException {
doGet(request, response);
}
}
通过一般的java类读取配置文件的内
package com.hbsi.dao;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
public class StudentDao {
private static String driver;
static{
//如果读取配置文件不是Servlet,而是一般的类,使用类加载器。
InputStream in = StudentDao.class.getClassLoader().getResourceAsStream("db.properties");
Properties prop = new Properties();
try {
prop.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driver =prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
}
public static Connection getConnection(){
return null;
}
public void insert(){
}
public void update(){
}
public void delete(){
}
}
5.ServletConfig和ServletContext的区别
– 整个Web应用只有一个ServletContext,在部署Web应用的时候,容器会建立这一个ServletContext对象,这个上下文对Web应用中的每个Servlet和JSP都可用。
– Web应用中的各个Servlet都有自己的ServletConfig,它只对当前Servlet有效。
在客户端缓存Servlet的输出
• 对于不经常变化的数据,在servlet中可以为其设置合理的缓存时间值,以避免浏览器频繁向服务器发送请求,提升服务器的性能。