1. ServletConfig
1.1 ServletConfig 基本介绍
- ServletConfig 类是为 Servlet 程序的配置信息的类
- Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建
- Servlet 程序默认是第 1 次访问的时候创建,ServletConfig 在 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象
1.2 ServletConfig 类能干什么
- 获取 Servlet 程序的 servlet-name 的值
- 获取初始化参数 init-param
- 获取 ServletContext 对象
1.3 ServletConfig 应用实例
● 需求: 编写 DBServlet.java 完成如下功能
- 在 web.xml 配置连接 mysql 的用户名和密码
- 在 DBServlet 执行 doGet()/doPost() 时,可以获取到 web.xml 配置的用户名和密码
- 示意图(思路分析)
● 代码实现
提示:具体看项目对应的代码
DBServlet.java
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 {
System.out.println("init" + config);
super.init(config);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//在DBServlet 执行 doGet()/doPost() 时,可以获取到web.xml配置的用户名和密码
//你是一个OOP程序员->现有的方法或对象来搞定
//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文件
<servlet>
<servlet-name>DBServlet</servlet-name>
<servlet-class>com.hspedu.servlet.DBServlet</servlet-class>
<!--配置信息,而不是硬编码到程序-->
<init-param>
<param-name>username</param-name>
<param-value>hsp</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>
优化:注解方式实现
@WebServlet(name = "DBServlet2", value = "/DBServlet2",initParams = {@WebInitParam(name = "user",value = "root"),@WebInitParam(name = "pwd",value = "123456")})
public class DBServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig();
String user = servletConfig.getInitParameter("user");
String pwd = servletConfig.getInitParameter("pwd");
System.out.println("user:"+user);
System.out.println("pwd:"+pwd);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
2. ServletContext
2.1 为什么需要 ServletContext
- 先看一个需求: 如果我们希望统计某个 web 应用的所有 Servlet 被访问的次数,怎么办?
- 方案 1-DB
- 方案 2-ServletContext
2.2 ServletContext 基本介绍
- ServletContext 是一个接口,它表示 Servlet 上下文对象
- 一个 web 工程,只有一个 ServletContext 对象实例
- ServletContext 对象 是在 web 工程启动的时候创建,在 web 工程停止的时销毁
- ServletContext 对象可以通过 ServletConfig.getServletContext 方法获得对 ServletContext
对象的引用,也可以通过 this.getServletContext()来获得其对象的引用。 - 由于一个 WEB 应用中的所有 Servlet 共享同一个 ServletContext 对象,因此 Servlet 对象之间可以通过 ServletContext 对象来实现多个 Servlet 间通讯。ServletContext 对象通常也被称之为域对象。【示意图】
2.3 ServletContext 可以做什么
- 获取 web.xml 中配置的上下文参数 context-param [信息和整个 web 应用相关,而不是
属于某个 Servlet] - 获取当前的工程路径,格式: /工程路径 =》 比如 /servlet
- 获 取 工 程 部 署 后 在 服 务 器 硬 盘 上 的 绝 对 路 径 ( 比 如
D:\hspedu_javaweb\servlet\out\artifacts\servlet_war_exploded)
- 像 Map 一样存取数据, 多个 Servlet 共享数据
2.4 应用实例
2.4.1 应用实例 1-获取工程相关信息
● 需求如下:
- 获取 web.xml 中配置的上下文参数 context-param
- 获取当前的工程路径,格式: /工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
● 代码实现 - 具体看 项目中的代码.
ServletContext_.java
public class ServletContext_ extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取web.xml的context-parameter
//1.1 获取到ServletContext对象 方式1
// ServletContext servletContext = servletConfig.getServletContext();
//1.2 获取到ServletContext对象
ServletContext servletContext = getServletContext();
//2. 获取website
String website = servletContext.getInitParameter("website");
String company = servletContext.getInitParameter("company");
//3. 获取项目的工程路径
String contextPath = servletContext.getContextPath();
//4. 获取项目发布后,正在的工作路径
// /表示我们的项目(发布后)的 根路径 D:\hspedu_javaweb\servlet\out\artifacts\servlet_war_exploded
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);
}
}
web.xml
<!--配置ServletContext_-->
<servlet>
<servlet-name>ServletContext_</servlet-name>
<servlet-class>com.hspedu.servlet.servletcontext.ServletContext_</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletContext_</servlet-name>
<url-pattern>/servletContext_</url-pattern>
</servlet-mapping>
<!--配置整个网站的信息-->
<context-param>
<param-name>website</param-name>
<param-value>http://www.baidu.com</param-value>
</context-param>
<context-param>
<param-name>company</param-name>
<param-value>百度</param-value>
</context-param>
2.4.2 应用实例 2-简单的网站访问次数计数器
需求分析/图解
- 需求: 完成一个简单的网站访问次数计数器:
- 使用 Chrome 访问 Servlet01, 每访问一次,就增加 1 访问次数,在后台输出,并将结果返回给浏览器显示
- 使用火狐访问 Servlet02,每访问一次,就增加 1 访问次数,在后台输出,并将结果返回给浏览器显示
OrderServlet.java
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());
// 法1
// //从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);
// }
// 法2
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);
}
}
PayServlet.java
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());
//法1
// //从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);
// }
//法2
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.java
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 中配置两个 servlet
<servlet>
<servlet-name>OrderServlet</servlet-name>
<servlet-class>com.hspedu.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.hspedu.servlet.servletcontext.PayServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PayServlet</servlet-name>
<url-pattern>/payServlet</url-pattern>
</servlet-mapping>
完成测试