一、ServletContext和ServletConfig
1.ServletContext对象:
- 解决的问题:
Request 解决了一次请求内的数据共享问题,session 解决了用户不同请求的数据共享问题,ServletContext解决了不同的用户的数据共享。
- 原理:
ServletContext 对象由服务器进行创建,一个项目只有一个对象。不管在项目的任意位置进行获取得到的都是同一个对象,那么不同用户发起的请求获取到的也就是同一个对象了,该对象由用户共同拥有。
- 特点:
(1)生命周期:
服务器启动到服务器关闭 。
(2)作用域:
在本项目内。
- 使用步骤:
(1)获取 ServletContext 对象;
(2)使用作用域进行共享数据流转;
(3)获取 web.xml 中的全局配置;
(4)获取 webroot 下项目资源流对象;
(5)获取 webroot 下资源绝对路径;
- 创建ServletContext对象的方法:
this.getServletContext();
this.getServletConfig().getServletContext();
req.getSession().getServletContext();
- 代码:
package com.zlw.context2;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
ServletContext对象:
作用:
解决了不同用户之间的数据共享问题
使用:
创建ServletContext对象
ServletContext sc1 = this.getServletContext();
ServletContext sc2 =this.getServletConfig().getServletContext();
ServletContext sc3=req.getSession().getServletContext();
存储用户共享数据
sc.setAttribute(String name,Object value);
获取用户共享数据
sc.getAttribute(String name);
删除共享数据
sc.removeAttribute(String name);
获取web.xml中的全局配置属性,作用:将部分动作和源文件进行解耦,我们只需要在xml配置文件中进行相关配置就会改变代码的执行效果。
sc.getInitParameter(String name);注意返回的是String类型数据
获取webRoot下的资源流对象
sc.getResourceAsStream(String path);
注意:
path为相对路径,写从webRoot开始查找资源的路径即可。
获取webRoot下的资源绝对路径
sc.getRealPath(String path);
注意:
path为相对路径,写从webRoot开始查找资源的路径即可。
特点:
服务器创建
所有用户共享
生命周期:
服务器开启到服务器关闭
* @author zhang
*
*/
@WebServlet("/contextA")
public class ServletContext3 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求编码格式
request.setCharacterEncoding("utf-8");
//设置响应编码格式
response.setContentType("text/html;charset=utf-8");
//获取请求信息
//处理请求信息
String str="我是用户共享数据!";
//获取ServletContext对象
ServletContext context = this.getServletContext();
//存储用户共享数据到ServletContext中
context.setAttribute("str", str);
//获取web.xml中的全局配置属性
String f=context.getInitParameter("flag");
if ("false".equals(f)) {
System.out.println("ServletContext3.service:打开资源");
} else {
System.out.println("ServletContext3.service:关闭资源");
}
//获取WebRoot下的资源流对象
// File file=new File("D:\\apache-tomcat-7.0.56\\webapps\\sc\\image");//绝对路径
InputStream is = context.getResourceAsStream("image/a.png");//相对路径
//获取webRoot下资源的绝对路径
String path=context.getRealPath("image/a.png");
System.out.println(path);
//处理响应信息
//直接响应
response.getWriter().write("数据已经在ServletContext中创建!");
//请求转发
//重定向
}
}
- web.xml文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!-- 配置全局配置属性 -->
<context-param>
<param-name>flag</param-name>
<param-value>true</param-value>
</context-param>
</web-app>
2.ServletConfig对象:
- 解决的问题:
使用ServletContext对象可以获取web.xml中的全局配置文件,在 web.xml 中每个 Servlet 也可以进行单独的配置,使用 ServletConfig 对象 获取配置信息。
- 作用:
ServletConfig 对象是 Servlet 的专属配置对象,每个 Servlet 都单独拥有一个 ServletConfig 对象,用来获取 web.xml 中的配置信息。
- 使用:
获取 ServletConfig 对象 。
获取 web.xml 中 servlet 的配置信息 。
- 代码示例:
package com.zlw.config;
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 TestServletConfig extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取ServletConfig对象
ServletConfig sg = this.getServletConfig();
//设置请求编码格式
req.setCharacterEncoding(sg.getInitParameter("code"));
//设置响应 的编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String flag = sg.getInitParameter("flag");
System.out.println(flag);
//获取用户请求信息
String uname = req.getParameter("uname");
//处理请求信息
System.out.println(uname);
//响应请求结果
}
}
- web.xml文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>TestServletConfig</servlet-name>
<servlet-class>com.zlw.config.TestServletConfig</servlet-class>
<!-- 配置当前Servlet的属性信息 -->
<init-param>
<param-name>flag</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>code</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>TestServletConfig</servlet-name>
<url-pattern>/config</url-pattern>
</servlet-mapping>
</web-app>
结果
二、网站访问次数统计:
实现同一用户不同次访问网页的次数累计统计:
- LoginServlet类:
package com.zlw.login;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应格式
resp.setContentType("text/html;charset=utf-8");
//获取Session中的数据
HttpSession session= req.getSession();
String str = (session.getAttribute("flag")==null?"":"用户名或密码错误!");
//销毁session
session.invalidate();
//获取请求信息
//处理请求信息
//响应处理结果
//直接响应
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<form action='user' method='get'>");
resp.getWriter().write("<font color='red'>"+str+"</font><br >");
resp.getWriter().write(" 用户名:<input type='text' name='uname' value=''/><br />");
resp.getWriter().write(" 密码:<input type='password' name='pwd' value=''/><br />");
resp.getWriter().write("<input type='submit' value='登录'/><br />");
resp.getWriter().write("</form>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
- UserServlet类:
package com.zlw.login;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//@WebServlet("/user")
public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname=req.getParameter("uname");
String pwd = req.getParameter("pwd");
//处理请求信息
//校验用户信息
if ("张三".equals(uname)&&"123".equals(pwd)) {
//登录成功
//获取ServletContext对象
ServletContext sc = this.getServletContext();
//获取计数器
Object obj = sc.getAttribute("nums");
//判断
if (obj!=null) {
//计数器数据自增
int nums=(int) obj;
nums=nums+1;
//存储计数器数据到ServletContext对象
sc.setAttribute("nums", nums);
} else {
sc.setAttribute("nums", 1);
}
//创建Session对象
HttpSession hs= req.getSession();
//存储数据
hs.setAttribute("uname", uname);
//处理响应结果(重定向到登录成功的Servlet)
resp.sendRedirect("main");
}else{
//登录失败
//创建session并增加登录失败标记
HttpSession session = req.getSession();
session.setAttribute("flag", "loginFalse");
//相应处理结果(重定向到登录页面)
resp.sendRedirect("login");
}
}
}
- MainServlet类:响应后的页面
package com.zlw.login;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//@WebServlet("/main")
public class MainServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
//获取ServletContext对象
ServletContext sc = this.getServletContext();
//获取计数器数据
int nums=(int) sc.getAttribute("nums");
//处理请求信息
//直接响应
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<h3>欢迎"+req.getSession().getAttribute("uname")+"访问尚学堂主页</h3>");
resp.getWriter().write("<hr />");
resp.getWriter().write("当前网页浏览器次数为:"+nums);
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
- NumServlet类:
package com.zlw.login;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
/**
* 1、在服务器关闭的时候将ServletContext中的计数器数据存储到nums.txt中
* 2、在服务器启动的时候将nums.txt中的数据存储到ServletContext中
* @author zhang
*
*/
public class NumServlet extends HttpServlet {
//在服务器启动的时候将nums.txt中的数据存储到ServletContext中
@Override
public void init() throws ServletException {
//获取ServletContext对象
ServletContext sc= this.getServletContext();
//获取nums.txt中存储的浏览器次数
//获取nums.txt的绝对路径(动态获取)
String path = sc.getRealPath("num/nums.txt");
//创建File对象
File f =new File(path);
//读取nums.txt中的数据
//获取资源流对象
BufferedReader br = null;
InputStreamReader is= null;
FileInputStream fs = null;
try {
fs = new FileInputStream(f);
is = new InputStreamReader(fs);
br = new BufferedReader(is);
//读取
String nums = br.readLine();
//将数据存储到ServletContext中
sc.setAttribute("nums", Integer.parseInt(nums));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//关闭资源
try {
fs.close();
is.close();
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//在服务器关闭的时候将ServletContext中的计数器数据存储到nums.txt中
@Override
public void destroy() {
//获取ServletContext对象
ServletContext sc= this.getServletContext();
//获取计数器数据
int nums = (int) sc.getAttribute("nums");
//将计数器数据存放到nums.txt文件中
//获取nums.txt文件的绝对路径(动态获取)
String path = sc.getRealPath("num/nums.txt");
//获取nums.txt的file对象
File f=new File(path);
//获取资源的流对象
BufferedWriter bw=null;
OutputStreamWriter osw = null;
FileOutputStream fos = null;
try {
//获取nums.txt的流对象
bw = new BufferedWriter(osw);
osw = new OutputStreamWriter(fos);
fos = new FileOutputStream(f);
//将数据写入到nums.txt中
bw.write(nums+"");
//刷新
bw.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//关闭流资源
try {
fos.close();
bw.close();
osw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
- 创建num目录及目录下的nums.txt文件:
- web.xml文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.zlw.login.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.zlw.login.UserServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>MainServlet</servlet-name>
<servlet-class>com.zlw.login.MainServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>NumServlet</servlet-name>
<servlet-class>com.zlw.login.NumServlet</servlet-class>
<load-on-startup>1</load-on-startup><!-- 配置Servlet服务器启动加载 -->
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>NumServlet</servlet-name>
<url-pattern>/num2</url-pattern>
</servlet-mapping>
</web-app>
结果
结果
网友评论