在编写servlet过程中,需要用到 ServletConfig、ServletContext对象,对这两种对象的介绍如下:
ServletContext对象:servlet容器在启动时会加载web应用,并为每个web应用创建唯一的servlet context对象,可以把ServletContext看成是一个Web应用的服务器端组件的共享内存,在ServletContext中可以存放共享数据。ServletContext对象是真正的一个全局对象,凡是web容器中的Servlet都可以访问。
servletConfig对象:用于封装servlet的配置信息。从一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对servlet自身有效,一个servlet的ServletConfig对象不能被另一个servlet访问。
在servlet中如何获取ServletContext对象和ServletConfig对象,请看下面代码:
[java] view plain copy
- import javax.servlet.ServletConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServlet;
- public class Servlet1 extends HttpServlet{
- @Override
- public void init() throws ServletException
- {
- ServletConfig config = this.getServletConfig();
- System.out.println("Servlet1 config=="+config);
- System.out.println("Servlet1 间接获取context==" +config.getServletContext() );
- System.out.println("Servlet1 直接获取context==" + this.getServletContext());
- System.out.println("Servlet1 param_value==" + config.getInitParameter("servlet1_param_name"));
- System.out.println("context_value==" + this.getServletContext().getInitParameter("context_param"));
- System.out.println("*********************************");
- }
- @Override
- public void service(ServletRequest req, ServletResponse resp)
- throws ServletException{
- }
- @Override
- public void destroy() {
- }
- }
Servlet2的代码:
[java] view plain copy
- import javax.servlet.ServletConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServlet;
- public class Servlet2 extends HttpServlet {
- @Override
- public void init() throws ServletException
- {
- ServletConfig config = this.getServletConfig();
- System.out.println("Servlet2 config=="+config);
- System.out.println("Servlet2 间接获取context==" +config.getServletContext());
- System.out.println("Servlet2 直接获取context==" + this.getServletContext());
- System.out.println("Servlet2 param_value==" + config.getInitParameter("servlet2_param_name"));
- System.out.println("context_value==" + this.getServletContext().getInitParameter("context_param"));
- System.out.println("*********************************");
- }
- @Override
- public void service(ServletRequest req, ServletResponse resp)
- throws ServletException{
- }
- @Override
- public void destroy() {
- }
- }
web.xml文件的配置:
[html] view plain copy
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.4"
- xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
- http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
- <servlet>
- <servlet-name>servlet_1</servlet-name>
- <servlet-class>com.test.servlet.Servlet1</servlet-class>
- <init-param>
- <param-name>servlet1_param_name</param-name>
- <param-value>value1</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet>
- <servlet-name>servlet_2</servlet-name>
- <servlet-class>com.test.servlet.Servlet2</servlet-class>
- <init-param>
- <param-name>servlet2_param_name</param-name>
- <param-value>value2</param-value>
- </init-param>
- <load-on-startup>0</load-on-startup>
- </servlet>
- <context-param>
- <param-name>context_param</param-name>
- <param-value>value3</param-value>
- </context-param>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
部署到tomcat中,然后启动服务,在控制台打印出如下信息:
Servlet2 config==org.apache.catalina.core.StandardWrapperFacade@13d422d
Servlet2 间接获取context==org.apache.catalina.core.ApplicationContextFacade@1123c5f
Servlet2 直接获取context==org.apache.catalina.core.ApplicationContextFacade@1123c5f
Servlet2 param_value==value2
context_value==value3
*********************************
Servlet1 config==org.apache.catalina.core.StandardWrapperFacade@14683c0
Servlet1 间接获取context==org.apache.catalina.core.ApplicationContextFacade@1123c5f
Servlet1 直接获取context==org.apache.catalina.core.ApplicationContextFacade@1123c5f
Servlet1 param_value==value1
context_value==value3
*********************************
通过控制台打印的信息可以得出如下结论:
1、在web.xml配置文件中,对没个servlet的配置里,有一项<load-on-startup></load-on-startup>,它的含义是:标记容器是否在启动的时候就加载这个servlet。当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。正数的值越小,启动该servlet的优先级越高。
servlet_2虽然配置在servlet_1后面,但是它的load-on-startup为0,启动的优先级高于servlet_1,所以servlet_2先启动。
2、获取ServletContext的两种方式,直接获取和间接获取,得到的对象都是同一个。同时在servlet1和servlet2中取得的ServletContext对象都是同一个对象,说明整个web应用都只有一个唯一的ServletContext实例;
3、servlet1与servlet2的serveletConfig对象是不一样的,说明ServletConfig对象的作用范围仅在servlet中。
一.ServletConfig和ServletContext
1.它们的作用和区别
1)作用
- 可以从web.xml中读取数据,给Servlet使用
它们都能够给Servlet预置参数
2)区别
- config和Servlet是1对1的关系
- context和Servlet是1对多的关系
Tomcat会保障它们和Servlet的关系
2.ServletConfig
1)场景介绍
- 假设开发一个网页游戏
- 如果在线人数达到最大值时,新登录的人需要排队
- 需要开发登录功能LoginServlet
- 在此Servlet内要获取在线人数最大值并加以判断
- 最大值maxonline要求可以配置
2)实现方式
- 将参数配置到web.xml内
- 该参数只给登录功能LoginServlet使用,使用config读取
3.ServletContext
1)场景介绍
- 项目通常都有很多查询功能,几乎每个查询都支持分页
- 分页的已知条件: 页码page, 每页显示行数size
- size要求可以配置,便于系统上线时实施人员去修改
2)实现方式
- 配置到web.xml中
- 因为多个功能都要使用该参数,所以使用context来读取它
4.ServletContext的特殊用途
1)特殊用途
- config和context典型的用途是读取web.xml中的常量(看2,3)
- 特殊用途:context还可以读写变量
- 用该对象读写的变量是可以被所有servlet共用的
- setAttribute()/getAttribute()
2)场景介绍
- 要统计软件的流量(访问量/访问人次)
- 任何人访问软件的任何功能,则流量+1
3)实现方式
案例一:ServletConfig的使用
[html] view plain copy
- package web;
- 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 LoginServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- /***
- * Tomcat创建servlet的逻辑:new之后,调用init()之前创建ServletConfig对象
- * LoginServlet s = new LoginServlet();
- * ServletConfig config = new ServletConfig();
- * 将web.xml中的数据加载到对象中
- * s.init(config);
- */
- @Override
- public void init(ServletConfig config) throws ServletException {
- super.init(config);
- String maxOnline = config.getInitParameter("maxOnline");
- System.out.println(maxOnline);
- }
- //模拟登陆
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse res)
- throws ServletException, IOException {
- //此config就是init()方法传入的那个
- ServletConfig config = getServletConfig();
- String maxOnline = config.getInitParameter("maxOnline");
- System.out.println(maxOnline);
- System.out.println("正在登录...");
- }
- }
配置文件:
[html] view plain copy
- <!-- LoginServlet案例(ServletConfig) -->
- <servlet>
- <servlet-name>login</servlet-name>
- <servlet-class>web.LoginServlet</servlet-class>
- <!-- 给此Servlet预置参数 -->
- <init-param>
- <param-name>maxOnline</param-name>
- <param-value>3000</param-value>
- </init-param>
- </servlet>
- <servlet-mapping>
- <servlet-name>login</servlet-name>
- <url-pattern>/login</url-pattern>
- </servlet-mapping>
访问一次该servlet输出结果:
3000
3000
正在登录...
=======================================================================
案例二:ServletContext的使用
[html] view plain copy
- package web;
- import java.io.IOException;
- 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 findDeptServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse res)
- throws ServletException, IOException {
- /**
- * tomcat启动时就会创建唯一的context
- * 并且会调用他的方法加载web.xml中的公用参数,任何servlet都可以使用
- */
- ServletContext context = getServletContext();
- String size = context.getInitParameter("size");
- System.out.println("分页查询部门数据:"+size);
- }
- }
[html] view plain copy
- package web;
- import java.io.IOException;
- 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 findEmpServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse res)
- throws ServletException, IOException {
- /**
- * tomcat启动时就会创建唯一的context
- * 并且会调用他的方法加载web.xml中的公用参数,任何servlet都可以使用
- */
- ServletContext context = getServletContext();
- String size = context.getInitParameter("size");
- System.out.println("分页查询员工数据:"+size);
- }
- }
配置文件:
[html] view plain copy
- <!-- (ServletCotext全局) 可以通过ServletContext读取该参数-->
- <context-param>
- <param-name>size</param-name>
- <param-value>20</param-value>
- </context-param>
- <!-- findDeptServlet和案例findEServlet -->
- <servlet>
- <servlet-name>findDept</servlet-name>
- <servlet-class>web.findDeptServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>findDept</servlet-name>
- <url-pattern>/findDept</url-pattern>
- </servlet-mapping>
- <servlet>
- <servlet-name>findEmp</servlet-name>
- <servlet-class>web.findEmpServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>findEmp</servlet-name>
- <url-pattern>/findEmp</url-pattern>
- </servlet-mapping>
分别访问servlet一次输出结果:
分页查询部门数据:20
分页查询员工数据:20
=============================================================
案例三:ServletContext的特殊使用,访问变量,将变量存入ServletContext,其他servlet都可使用
一般一般WEB项目中都有1-2个这样的Servlet
[html] view plain copy
- package web;
- import javax.servlet.ServletContext;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- public class InitServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- /**
- * 该Servlet不负责处理具体的业务,只用来在Tomcat启动时初始化数据
- * 一般WEB项目中都有1-2个这样的Servlet
- * init()或init(ServletConfig config)两种方法都可以
- */
- @Override
- public void init() throws ServletException {
- super.init();
- ServletContext context = getServletContext();
- //将数据保存在context对象中,默认访问量为0
- context.setAttribute("count", 0);
- }
- }
在findDeptServlet和findEmpServlet中添加如下代码:
[html] view plain copy
- //统计访问量
- Integer count = (Integer)context.getAttribute("count");
- //更新count,重新写入ServletContext
- context.setAttribute("count", ++count);
- System.out.println("当前访问量:"+count);
配置文件如下:
[html] view plain copy
- <!-- InitServlet案例 servlet-mapping可以不写 -->
- <servlet>
- <servlet-name>init</servlet-name>
- <servlet-class>web.InitServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
分别访问findDeptServlet和findEmpServlet多次输出结果:
[html] view plain copy
- 分页查询员工数据:20
- 当前访问量:1
- 分页查询员工数据:20
- 当前访问量:2
- 分页查询部门数据:20
- 当前访问量:3
- 分页查询员工数据:20
- 当前访问量:4
- 分页查询部门数据:20
- 当前访问量:5
总结:
1.当需要给Servlet预置参数时使用这样的对象
2.若参数只给一个Servlet使用,用ServletConfig
3.若参数只给多个Servlet使用,用ServletContext