web会为每个应用都创建一个ServletContext对象,当容器分布在多个虚拟机上时,web应用在所分布的每个虚拟机上都拥有一个ServletContext实例.
可以作为web应用的全局变量被所有Servlet和JSP访问.
下面我们来学习如何使用:
一,获取初始化参数
1) 新建测试servlet类:
package com.example.servlet;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Properties;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 从本地读取文件,文件复制(复习)
* @author Administrator
*
*/
public class FileServlet extends HttpServlet{
private static final long serialVersionUID = 4943970226851618892L;
private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.config = config;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
String uri = req.getRequestURI();
String path = uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf(".action"));
/**
* 获取初始化参数
* 在web.xml中配置了初始化参数,在servlet实例化后会调用init方法
* 自动将对象封装到ServletConfig中
*/
if ("/get_init_param".equals(path)) {
PrintWriter out = resp.getWriter();
//通过参数名获取参数
out.println(config.getInitParameter("msg"));
//获取参数数组
Enumeration<String> e = config.getInitParameterNames();
while (e.hasMoreElements()) {
String name = e.nextElement();
String value = config.getInitParameter(name);
out.println("参数名:"+name+",参数值:"+value);
}
out.flush();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(req, resp);
}
}
这里说明一下,ServletConfig的获取途径:
可以重写init方法获取,也可以不重写,直接用this.getServletConfig()获取。
2) 在web.xml中配置映射以及初始化参数 <servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>com.example.servlet.FileServlet</servlet-class>
<init-param>
<param-name>msg</param-name>
<param-value>我是初始化参数分割线</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
3) 测试:http://localhost:8088/webDemo/get_init_param.action
二,记录访问次数
1) 继续在doGet中添加测试代码:
/**
* 使用ServletContext共享对象计算请求次数
* WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用
*/
if ("/get_visit_count".equals(path)) {
//从request对象中获取
// ServletContext servletContext = req.getServletContext();
//从ServletConfig对象中获取
// ServletContext servletContext = config.getServletContext();
// ServletContext servletContext = this.getServletConfig().getServletContext();
//从当前对象中获取
ServletContext servletContext = this.getServletContext();
Integer count = (Integer) servletContext.getAttribute("count");
if (count == null) {
count = 0;
}
count++;
servletContext.setAttribute("count", count);
PrintWriter out = resp.getWriter();
out.println("第"+count+"次访问");
out.flush();
out.close();
}
这里说明一下,ServletConfig的获取途径:
可以从request对象中获取,也可以从ServletConfig对象中获取,还可以直接用this.getServletContext()获取
2) 测试:http://localhost:8088/webDemo/get_visit_count.action
三,获取静态资源文件,先看代码:
/**
* 使用servletContext读取资源文件
*
*/
if ("/get_file".equals(path)) {
PrintWriter out = resp.getWriter();
//读取src目录下的properties配置文件
readSrcDirPropCfgFile(out);
out.println("<br/>");
//读取webapp目录下的properties配置文件
readWebRootDirPropCfgFile(out);
out.flush();
out.close();
}
/**
* 使用ClassLoad类加载器读取资源文件
* 不适合装载大文件,否则会导致jvm内存溢出
*/
if ("/get_classLoad_file".equals(path)) {
PrintWriter out = resp.getWriter();
ClassLoader loader = this.getClass().getClassLoader();
//类装载器读取src目录下的文件,只用提供相对路径
InputStream in = loader.getResourceAsStream("/log.properties");
if (in != null) {
Properties prop = new Properties();
prop.load(in);
String name = prop.getProperty("db.name");
String user = prop.getProperty("db.user");
String password = prop.getProperty("db.password");
out.println(MessageFormat.format(
"name={0},user={1},password={2}", name,user,password));
}
out.flush();
out.close();
}
/**
* 读取大文件,写到本地磁盘
*/
if ("/copy_file".equals(path)) {
ServletContext context = config.getServletContext();
InputStream in = context.getResourceAsStream("WEB-INF/classes/log.properties");
OutputStream out = new FileOutputStream("H:\\log.properties");
if (in != null && out != null) {
byte buffer[] = new byte[1024];
int i = 0;
while ((i = in.read(buffer)) != -1) {
out.write(buffer,0,i);
}
}
out.flush();
out.close();
in.close();
}
}
/**
* 1,读取src目录下的properties配置文件
* @param resp
* @throws IOException
*/
private void readSrcDirPropCfgFile(PrintWriter out) throws IOException {
//src目录文件需要读取tomcat编译后的目录
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/log.properties");
if (in != null) {
Properties prop = new Properties();
prop.load(in);
Enumeration<?> e = prop.propertyNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = prop.getProperty(name);
out.println(name+"="+value);
}
}
in.close();
}
/**
* 读取webapp目录下的配置文件
* @param out
* @throws IOException
*/
private void readWebRootDirPropCfgFile(PrintWriter out) throws IOException {
//根目录可以使用相对路径
InputStream in = this.getServletContext().getResourceAsStream("/conf/conf.properties");
if (in != null) {
Properties prop = new Properties();
prop.load(in);
String name = prop.getProperty("db.name");
String user = prop.getProperty("db.user");
String password = prop.getProperty("db.password");
out.println(MessageFormat.format(
"name={0},user={1},password={2}", name,user,password));
}
in.close();
}
代码注释很清楚了,需要注意的是文件加载目录,下面我们来测试:
1) http://localhost:8088/webDemo/get_file.action
2) http://localhost:8088/webDemo/get_classLoad_file.action
3) http://localhost:8088/webDemo/copy_file.action
我们演示了如何复制文件到本地磁盘,其实稍微改一下,就可以实现从浏览器端下载文件到客户端,
更改代码如下:
/**
* 读取大文件,写到本地磁盘
*/
if ("/copy_file".equals(path)) {
ServletContext context = config.getServletContext();
InputStream in = context.getResourceAsStream("WEB-INF/classes/log.properties");
//读写文件到本地磁盘
// OutputStream out = new FileOutputStream("H:\\log.properties");
/*
* 下载文件到浏览器--客户端
* 1,设置下载文件名为load_log.properties,告诉浏览器以附件形式下载文件
* 2,更改输出流
*/
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("load_log.properties", "UTF-8"));
OutputStream out = resp.getOutputStream();
if (in != null && out != null) {
byte buffer[] = new byte[1024];
int i = 0;
while ((i = in.read(buffer)) != -1) {
out.write(buffer,0,i);
}
}
out.flush();
out.close();
in.close();
}
}
启动访问:localhost:8088/webDemo/copy_file.action
可以看到浏览器已经帮我们下载了文件,文件名就是load_log.properties
=======================================================================================
关于文件的下载,上传,在页面如何显示等问题,我们下篇继续,java_web 学习记录(六):文件上传和下载