目录
ServletConfig
ServletConfig 基本介绍
ServletConfig 类能干什么
为什么需要 ServletContext
1. 方案 1-DB
2. 方案 2-ServletCntext
代码实战
ServletContext
ServletContext 基本介绍
ServletContext 可以做什么
代码实战
代码实战2
ServletConfig
ServletConfig 基本介绍
ServletConfig 类是为 Servlet 程序的配置信息的类
Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建
Servlet 程序默认是第 1 次访问的时候创建,ServletConfig 在 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象
ServletConfig 类能干什么
获取 Servlet 程序的 servlet-name 的值
获取初始化参数 init-param
获取 ServletContext 对象
为什么需要 ServletContext
先看一个需求:如果我们希望统计某个 web 应用的所有 Servlet 被访问的次数,怎么办?
1. 方案 1-DB
2. 方案 2-ServletCntext
代码实战
● 需求: 编写 DBServlet.java 完成如下功能
1. 在 web.xml 配置连接 mysql 的用户名和密码
2. 在 DBServlet 执行 doGet()/doPost() 时,可以获取到 web.xml 配置的用户名和密
public class DBServlet extends HttpServlet {
/**
* 梳理ServletConfig config 使用流程
* 1. 当DBServlet对象初始化时, tomcat会同时创建一个 ServletConfig对象
* 2. 这时如果DBServlet init() 方法中你调用 super.init(config);
* 3. 调用 父类 GenericServlet
* public void init(ServletConfig config) throws ServletException {
* this.config = config;
* this.init();
* }
* 这时就会把 Tomcat创建的 ServletConfig对象赋给 GenericServlet的属性 config
* 4. 因此如果你重写init()方法,记住如果你想在其它方法通过 getServletConfig() 方法获取ServletConfig
* , 则一定要记住 调用 super.init(config);
* @param config
* @throws ServletException
*/
@Override
public void init(ServletConfig config) throws ServletException {
//ConcurrentHashMap, 是一个线程安全的容器.
System.out.println("init" + config);
super.init(config);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//在DBServlet 执行 doGet()/doPost() 时,可以获取到web.xml配置的用户名和密码
//DBServlet的父类GenericServlet有getServletConfig()
/**
* 解读
* 1. getServletConfig() 方法是 GenericServlet
* 2. 返回的 servletConfig对象是 GenericServlet private transient ServletConfig config;
* 3. 当一个属性被 transient 修饰,表示该属性不会被串行化(有些重要信息,不希望保存到文件)
*/
ServletConfig servletConfig = getServletConfig();
System.out.println("doPost=" + servletConfig);
String username = servletConfig.getInitParameter("username");
String pwd = servletConfig.getInitParameter("pwd");
System.out.println("初始化参数username= " + username);
System.out.println("初始化参数pwd= " + pwd);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
xml配置
<!--配置DBServlet-->
<servlet>
<servlet-name>DBServlet</servlet-name>
<servlet-class>com.servlet.DBServlet</servlet-class>
<!--配置信息,而不是硬编码到程序-->
<init-param>
<param-name>username</param-name>
<param-value>xxx</param-value>
</init-param>
<init-param>
<param-name>pwd</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DBServlet</servlet-name>
<url-pattern>/db</url-pattern>
</servlet-mapping>
ServletContext
ServletContext 基本介绍
1. ServletContext 是一个接口,它表示 Servlet 上下文对象
2. 一个 web 工程,只有一个 ServletContext 对象实例
3. ServletContext 对象 是在 web 工程启动的时候创建,在 web 工程停止的时销毁
4. ServletContext 对象可以通过 ServletConfig.getServletContext 方法获得对 ServletContext对象的引用,也可以通过 this.getServletContext()来获得其对象的引用。
5. 由于一个 WEB 应用中的所有 Servlet 共享同一个 ServletContext 对象,因此 Servlet 对象之间可以通过 ServletContext 对象来实现多个 Servlet 间通讯。ServletContext 对象通常也被称之为域对象。【示意图】
ServletContext 可以做什么
1. 获取 web.xml 中配置的上下文参数 context-param [信息和整个 web 应用相关,而不是属于某个 Servlet]
2. 获取当前的工程路径,格式: /工程路径 =》 比如 /servlet
3. 获取工程部署后在服务器硬盘上的绝对路径如D:\xx\xx\xx\xx
4. 像 Map 一样存取数据多个 Servlet 共享数据
代码实战
● 需求如下:
1. 获取 web.xml 中配置的上下文参数 context-param
2. 获取当前的工程路径,格式: /工程路径
3. 获取工程部署后在服务器硬盘上的绝对路径
public class ServletContext_ extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取web.xml的context-parameter
//1.获取到ServletContext对象
ServletContext servletContext = getServletContext();
//2. 获取website
String website = servletContext.getInitParameter("website");
String company = servletContext.getInitParameter("company");
//3. 获取项目的工程路径
String contextPath = servletContext.getContextPath();
//4. 获取项目发布会,正在的工作路径
// /表示我们的项目(发布后)的 根路径
String realPath = servletContext.getRealPath("/");
System.out.println("项目路径= " + contextPath);// /servlet
System.out.println("website= " + website);
System.out.println("company= " + company);
System.out.println("项目发布后的绝对路径= " + realPath);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
代码实战2
网站访问次数计数器
创建PayServlet
public class PayServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取到ServletContext对象
ServletContext servletContext = getServletContext();
// System.out.println("PayServlet servletContext= " +
// servletContext + " 运行类型=" + servletContext.getClass());
//
// //从servletContext获取 visit_count 属性 k-v
// Object visit_count = servletContext.getAttribute("visit_count");
// //判断visit_count是否为null
// if (visit_count == null) {//说明是第1次访问网站
// servletContext.setAttribute("visit_count", 1);
// visit_count = 1;
// } else { //是第二次或以后
// //取出visit_count属性的值+1
// visit_count = Integer.parseInt(visit_count + "") + 1;
// //放回到servletContext
// servletContext.setAttribute("visit_count", visit_count);
// }
Integer visit_count = WebUtils.visitCount(servletContext);
//输出显示
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>新网站被访问的次数是" + visit_count + "</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
创建OrderServlet
public class OrderServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取到ServletContext对象
ServletContext servletContext = getServletContext();
// System.out.println("OrderServlet servletContext= " +
// servletContext + " 运行类型=" + servletContext.getClass());
// //从servletContext获取 visit_count 属性 k-v
// Object visit_count = servletContext.getAttribute("visit_count");
// //判断visit_count是否为null
// if (visit_count == null) {//说明是第1次访问网站
// servletContext.setAttribute("visit_count", 1);
// visit_count = 1;
// } else { //二次或以后
// //取出visit_count属性的值+1
// visit_count = Integer.parseInt(visit_count + "") + 1;
// //放回到servletContext
// servletContext.setAttribute("visit_count", visit_count);
// }
Integer visit_count = WebUtils.visitCount(servletContext);
//输出显示
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>新网站被访问的次数是" + visit_count + "</h1>");
writer.flush();
writer.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
创建WebUtils
public class WebUtils {
//这个方法就是对访问的次数累积,同时返回次数
public static Integer visitCount(ServletContext servletContext) {
//从servletContext获取 visit_count 属性 k-v
Object visit_count = servletContext.getAttribute("visit_count");
//判断visit_count是否为null
if (visit_count == null) {//说明是第1次访问网站
servletContext.setAttribute("visit_count", 1);
visit_count = 1;
} else { //二次或以后
//取出visit_count属性的值+1
visit_count = Integer.parseInt(visit_count + "") + 1;
//放回到servletContext
servletContext.setAttribute("visit_count", visit_count);
}
return Integer.parseInt(visit_count + "");
}
}
在web.xml 中配置两个 servle
<servlet>
<servlet-name>OrderServlet</servlet-name>
<servlet-class>com.servlet.servletcontext.OrderServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OrderServlet</servlet-name>
<url-pattern>/orderServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>PayServlet</servlet-name>
<servlet-class>com.servlet.servletcontext.PayServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PayServlet</servlet-name>
<url-pattern>/payServlet</url-pattern>
</servlet-mapping>