您的位置:首页 > 编程语言 > Java开发

JavaWeb 之 servletConfig,servletContext

2012-09-15 13:22 507 查看

1.1 Tip:ServletConfig对象


在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。

当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

获取初始化参数信息

package cn.xushuai;

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 SlConfigDemo extends HttpServlet {
private static final long serialVersionUID = 1L;

@Override
protected  void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {

//可以直接通过(父类已经复写了init()方法)
ServletConfig config = this.getServletConfig();
String value = config.getInitParameter("data");
System.out.println(value);
//获取所有的初始化参数信息
ServletConfig config2 = this.getServletConfig();
Enumeration e = config2.getInitParameterNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = this.getServletConfig().getInitParameter(name);
System.out.println(name + "..." + value);
}
}

protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}


举例说明该对象的作用:

1、获得字符集编码(码表不确定,通过ServletConfig来配置)

2、获得数据库连接信息(用户名,密码等可能改变的属性,通过ServletConfig来配置,提高灵活性。)

3、获得配置文件,查看struts案例的web.xml文件

1.2 Tip:ServletContext对象
WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。在停掉服务器,

或者WEB应用移除时,ServletContext对象被销毁。

ServletContext对象被包含在ServletConfig对象中,开发人员在编写servlet时,可以通过ServletConfig.getServletContext

方法获得对ServletContext对象的引用。

由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。

ServletContext对象通常也被称之为context域对象。

ServletContext 域:

1. 这是一个容器。

2. servletContext域,这句话说明了容器的作用范围,也就是应用程序范围

1.3 Tip:ServletContext应用
多个Servlet通过ServletContext对象
package cn.itcast;

import java.io.IOException;
import java.io.PrintWriter;

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 ServletDemo6 extends HttpServlet {
//servletContext示例
public void doGet(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {

//得到servletContext方式一
ServletContext context=this.getServletConfig().getServletContext();

//方式二
ServletContext context2=this.getServletContext();
String data="aaaaa";
context.setAttribute("data", data);
}
}


package cn.itcast;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
servletContext域:1,是一个容器 2,作用范围是应用程序范围
*/
public class ServletDemo8 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String value = (String) this.getServletContext().getAttribute("data");
response.getOutputStream().write(value.getBytes());
}
}

1.4 Tip:1.4获取web应用的初始化参数
<context-param>

<param-name>data</param-name>

<param-value>zzzz</param-value>

</context-param>
this.getServletcontext().getAttribute("data");

1.5 Tip:实现servlet的转发
RequestDispatcherrd=this.getServletContext().getRequestDispatcher("/1.jsp");

rd.forward(request,response);

1.6 Tip:利用ServletContext对象读取资源文件
读取资源文件的三种方式

package cn.xushuai;

import java.io.File;
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 ReadProperties extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//test1();
test2();
//test3();
}
private void test1() throws IOException {
//方式1
//db.properties放在 src目录下,因为该目录下的资源文件发布时会发到/WEB-INF/classes目录下

//InputStream in = this.getServletContext().getResourceAsStream("C:/apache-tomcat-6.0.35/webapps/day05/WebContent/WEB-INF/classes/jd.properties");
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/jd.properties");
Properties props1 = new Properties();
props1.load(in);
//System.out.println(props1.getProperty("url"));
System.out.println(props1.getProperty("username"));
}

private void test2()
throws IOException, FileNotFoundException {

//传统方式,启动服务器同时启动java虚拟机,所以要得到虚拟机的启动目录,在此目录下建立一个classes文件夹存入db.properties
FileInputStream in2 =new FileInputStream("classes/jd.properties");
Properties props2 =new Properties();
props2.load(in2);

System.out.println(props2.getProperty("username"));
System.out.println(props2.getProperty("password"));
}

private void test3() throws FileNotFoundException,
IOException {

//通过sevrletContext得到绝对路劲,再通过传统方法读取(文件下载),可以获取资源的名称
String path = this.getServletContext().getRealPath("/WEB-INF/classes/jd.properties");
String filename = path.substring(path.lastIndexOf("\\")+1);

System.out.println("当前读取到的资源名称是"+" : "+filename);
FileInputStream in2 = new FileInputStream(path);
Properties props2=new Properties();
props2.load(in2);
System.out.println("当前读取到的资源是:");
System.out.println(props2.getProperty("username"));
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub

doGet(request,response);
}
}

1.7 Tip:WEB应用中的普通Java程序如何读取资源文件.
如果读取资源文件的程序不是servlet的话,就只能通过类转载器去读了,文件不能太大,

注意:由于类加载器只加载一次,所以若想读取更新后的数据,要先通过类加载的方式获得路径,然后再读取

package cn.it;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.itcast.dao.UserDao;

//servlet调用其它程序,在其它程序中如何去读取配置文件
//通过类装载器
public class ServletDemo12 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
UserDao user=new UserDao();
user.update();
}
}


package cn.itcast.dao;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

//如果读取资源文件的程序不是servlet的话,
//就只能通过类转载器去读了,文件不能太大
//用传递参数方法不好,耦合性高
public class UserDao {

private static Properties dbconfig=new Properties();
//只读一次,所以放在静态代码块中
static {
InputStream in=UserDao.class.getClassLoader().getResourceAsStream("db.properties");
try {
dbconfig.load(in);
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
//上面代码类装载器只装载一次,下面代码先用类装载的方式得到路径,再通过普通方式去读取。这样可以读取到更新后的数据
URL url=UserDao.class.getClassLoader().getResource("db.properties");
String str=url.getPath();
//file:/C:/apache-tomcat-7.0.22/webapps/day05/WEB-INF/classes/db.properties
try {
InputStream in2=new FileInputStream(str);
try {
dbconfig.load(in2);
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
} catch (FileNotFoundException e1) {
throw new ExceptionInInitializerError(e1);
}
}
public void update() {
System.out.println(dbconfig.get("url"));
}
}

1.8 Tip:Servlet高级应用—Servlet与缓存
1、设置缓存的两种场景:

场景一:对于不经常变化的数据,在servlet中可以为其设置合理的缓存时间值,以避免浏览器频繁向服务器发送请求,提升服务器的性能。

场景二:如果要实现一种高级功能,即客户端请求动态web资源时,动态web资源发现发给客户端的数据更新了,就给客户端发送最新的数据,

如果发现数据没有更新,则动态web资源就要客户端就去访问它自己缓存的数据。此种情况可以通过覆写动态web资源(即servlet)的 getLastModify方法予以实现。

2、getLastModified方法

1> getLastModified方法由service方法调用,默认情况下,getLastModified方法返回一个负数,开发人员在编写servlet时,如果不覆

盖getLastModified方法,则每次访问servlet时,service方法发现getLastModified方法返回负数,它就会调用doXXX方法向客户端返

回最新的数据。此种情况下,服务器在向客户端返回doXXX方法返回的数据时,不会在数据上加Last-Modified头字段。

2> 如果编写servlet时,覆盖了getLastModified方法,并返回某一个时间值,则客户端访问Servlet时,service方法首先会检查客户端

是否通过If-Modified-Since头字段带一个时间值过来。如果没有的话,则service方法会调用doXXX方法向客户端返回最新的数据。在

返回数据时,service方法还会调用getLastModified方法得到一个时间值,并以这个时间值在数据上加上一个Last-Modified头字段。

(即通知客户端缓存数据)

3> 客户端在访问servlet时,如果通过If-Modified-Since头字段带了一个时间值过来,则service方法在调用doXXX方法之前,它会先调用 getLastModified方法,得到一个时间值,并与客户端带过来的时间值进行比较,如果比客户端的时间值要新,则service方法调用doXXX

方法向客户端返回最新的数据。如果要旧,则service方法而不会调用doXXX方法向客户端返回数据,而是返回一个304的状态码给客户端,

通知客户端在拿它缓存中的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: