day15-Servlet04
Servlet04
12.ServletConfig
12.1ServletConfig基本介绍
- ServletConfig类是为Servlet程序配置信息的类
- Servlet对象和ServletConfig对象都是由Tomcat负责创建
- Servlet对象默认是第一次访问的时候创建,ServletConfig在Servlet对象创建的时候,就创建一个对应的ServletConfig对象
12.2ServletConfig作用
- 获取Servlet程序的servlet-name的值
- 获取初始化参数init-param
- 获取ServletContext对象(上下文对象)
12.3ServletConfig应用实例
例子
需求:编写DBServlet.java,完成如下功能
在web.xml配置连接mysql的用户名和密码
在DBServlet执行doGet()或者doPost()时,可以获取到web.xml配置的用户名和密码
思路分析:
浏览器发送请求,Tomcat去创建DBServlet,DBServlet去web.xml文件中去获取配置的参数,获取的方法有两种:一是使用dom4j,二是使用ServletConfig类

web.xml配置Servlet:
<!--配置DBServlet-->
<servlet>
<servlet-name>DBServlet</servlet-name>
<servlet-class>servlet.DBServlet</servlet-class>
<!--为该Servlet配置初始参数-->
<init-param>
<!--参数名-->
<param-name>username</param-name>
<!--参数值-->
<param-value>jack</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>
DBServlet:
package servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class DBServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
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();
String username = servletConfig.getInitParameter("username");
String pwd = servletConfig.getInitParameter("pwd");
System.out.println("初始化参数username=" + username);
System.out.println("初始化参数pwd=" + pwd);
}
}
浏览器访问DBServlet时,后台输出:

问题一:在doPost方法中可以得到servletConfig,在doGet方法也可以得到servletConfig,那么这两个servletConfig是同一个servletConfig吗?
答:是同一个servletConfig。
先来看一个例子
在上述的DBServlet中重写init方法,并且分别在init和doPost方法中输出ServletConfig对象
package servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class DBServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init()=" + config);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
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);
}
}
redeployTomcat,在浏览器重新访问DBServlet,会发现出现了500错误,这表明服务器内部运行出现错误

查看控制台输出,发现doPost方法竟然输出了null

在DBServlet中的init方法加上语句super.init(config);

redeployTomcat,重新访问浏览器,会发现访问DBServlet成功,后台输出变正常了

问题二:这是为什么呢?
我们先来梳理ServletConfig config的使用流程
当DBServlet对象初始化时,Tomcat会同时创建一个ServletConfig对象
如果DBServlet init()方法中调用了super.init(config);
就会调用父类GenericServlet的init方法:
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
这时就会把Tomcat创建的ServletConfig对象赋给GenericServlet的属性config
因此如果要重写init()方法,记住如果你想在其他方法通过getServletConfig()获取ServletConfig,则一定要记住调用super.init(config);
回到问题二:
如果没有把tomcat创建的ServletConfig,赋值给GenericServlet的属性config。那么GenericServlet的属性config的值就为null,而doPost或者doGet方法通过getServletConfig()拿到的就是GenericServlet的属性config,因此就会输出null。
侧面证实了方法中获取的servletConfig是同一个对象(问题一)
因此上面的例子中,浏览器访问DBServlet,发现出现了500错误的原因是,doPost方法中获取了为null的ServletConfig对象中的属性

13.ServletContext
13.1为什么需要ServletContext
先来看一个需求:如果我们希望统计某个web应用的所有Servlet被访问的次数,怎么办?
方案一:使用DB

方案二:使用ServletContext

13.2ServletContext基本介绍
ServletContext是一个接口,它表示Servlet上下文对象
一个web工程中,只有一个ServletContext对象实例
ServletContext对象是在web工程启动的时候创建的,在web工程停止的时候销毁
可以通过ServletConfig.getServletContext方法获得对ServletContext对象的应用,也可以通过this.getServletContext()来获得其对象的引用
由于一个web应用中的所有Servlet共享一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现多个Servlet间的通信。ServletContext对象通常也被称为域对象。

13.3ServletContext可以做什么
获取web.xml文件中配置的上下文参数context-param [信息和整个web应用相关,而不是属于某个Servlet]
获取当前的工程路径,格式:/工程路径
获取工程部署后在服务器硬盘上的绝对路径
比如 D:\IDEA-workspace\servlet\out\artifacts\servlet_war_exploded
向Map一样存取数据,多个Servlet共享数据
13.4应用实例
13.4.1应用实例1-获取工程相关信息
需求如下:
- 获取web.xml中配置的上下文参数context-param
- 获取当前的工程路径,格式:/工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
配置ServletContext_: 在web.xml文件增加相关配置
<!--配置ServletContext_-->
<servlet>
<servlet-name>ServletContext_</servlet-name>
<servlet-class>com.li.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.lili.net</param-value>
</context-param>
<context-param>
<param-name>company</param-name>
<param-value>lili有限公司</param-value>
</context-param>
ServletContext_:
package com.li.servlet.servletcontext;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class ServletContext_ extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
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");
System.out.println("website= " + website);
System.out.println("company= " + company);
//3.获取项目的工程路径
String contextPath = servletContext.getContextPath();
System.out.println("项目路径= " + contextPath);// /servlet_demo
//4.得到项目发布后真正的工作路径
//这里的斜杠/表示我们的项目发布后的根路径 D:\IDEA-workspace\servlet_demo\out\artifacts\servlet_demo_war_exploded
String realPath = servletContext.getRealPath("/");
System.out.println("项目发布后的绝对路径= " + realPath);
}
}
浏览器访问ServletContext_:

后台输出:

13.4.2应用实例2-简单的网站访问次数统计器
需求:完成一个简单的网站访问次数统计器
不管使用什么浏览器,每访问一次Servlet,就增加1访问次数,在后台输出,并将结果返回给浏览器显示

WebUtils.java:
package com.li.servlet.servletcontext;
import javax.servlet.ServletContext;
public class WebUtils {
//该方法对访问网站的次数累加,同时返回次数
public static Integer visitCount(ServletContext servletContext) {
//从servletContext获取 visit_count 属性 k-v
Object visit_count = servletContext.getAttribute("visit_count");
//判断visit_count是否为空
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 + "");
}
}
Servlet01.java:
package com.li.servlet.servletcontext;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = {"/Servlet01"})
public class Servlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取到ServletContext对象
ServletContext servletContext = getServletContext();
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();
}
}
Servlet02.java:
package com.li.servlet.servletcontext;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = {"/Servlet02"})
public class Servlet02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取到ServletContext对象
ServletContext servletContext = getServletContext();
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();
}
}
redeployTomcat,在不同的浏览器分别访问Servlet01和Servlet02:

day15-Servlet04的更多相关文章
- python_way day15 HTML-DAY2 HTML-DAY2、JS
python_way day15 HTML-DAY2 html-css回顾 javascript 一.html-css回顾 1.input与+,-号的写法 <!DOCTYPE html> ...
- Spark Streaming揭秘 Day15 No Receivers方式思考
Spark Streaming揭秘 Day15 No Receivers方式思考 在前面也有比较多的篇幅介绍了Receiver在SparkStreaming中的应用,但是我们也会发现,传统的Recei ...
- Python之路,Day15 - Django适当进阶篇
Python之路,Day15 - Django适当进阶篇 本节内容 学员管理系统练习 Django ORM操作进阶 用户认证 Django练习小项目:学员管理系统设计开发 带着项目需求学习是最有趣 ...
- ##DAY15——UICollectionView
DAY15——UICollectionView 创建UICollectionView //创建一个布局对象,采用系统布局类UICollectionViewFlowLayout UICollection ...
- 【JAVA零基础入门系列】Day15 对象的比较
最近一直有事,博客也停笔了一段时间,十分抱歉. 这一篇主要讲讲对象的比较,什么是对象的比较,我们知道两个数值类型只需要用"=="符号即可进行相等判断,但如果是两个Goods对象呢? ...
- day15.Python内置函数
作用域相关 locals() -- 获取执行本方法所在命名空间的局部变量的字典 globals() -- 获取全局变量的字典 print(locals()) print(globals()) {'_ ...
- 11.2 正睿停课训练 Day15
目录 2018.11.2 正睿停课训练 Day15 A 郁闷的小G(二分) B 小G的树(树形DP) C 数的距离(思路) 考试代码 B C 2018.11.2 正睿停课训练 Day15 时间:3.5 ...
- python开发学习-day15(前端部分知识、web框架、Django创建项目)
s12-20160430-day15 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...
- Day15模块(导入,使用)
Day15模块 什么是模块: 一系列功能的集合体 一个py文件就是一个模块 aaa.py就是aaa模块 模块四种形式: 内置的模块 py文件 第三方的 包 模块三种来源:内置的,第三方,自定义 为什么 ...
- 学习日常笔记<day15>mysql基础
1.数据库入门 1.1数据库软件 数据库:俗称数据的仓库,方便管理数据的软件(或程序) 1.2市面上数据库软件 Oracle,甲骨文公司的产品. 当前最流行应用最广泛的数据库软件.和java语言兼容非 ...
随机推荐
- n【c#】委托:delegate 学习笔记
类似于c/c++的指针,只不过c#的委托存储的是某个方法的调用,派生子System.Delegate
- DES|3DES|AES|RSA|DH | CA | SSL(HTTPS)
1.对称密钥算法: 加解密速度块,算法使安全的,已知算法无法推出密钥.但是密钥的分发困难. DES:对称密钥算法,是一种块加密算法,只有一个密钥.加解密都是用一个密钥. 3DES:与DES一样,可以认 ...
- Helm安装ingress-nginx-4.1.4
Application version 1.2.1 Chart version 4.1.4 获取chart包 helm fetch ingress-nginx/ingress-nginx --vers ...
- 阿色全息脑图,及制作软件AHMM
阿色全息脑图 AHMM 全息脑图是按照大系统观原理开发的新型思维工具,用于升维思考. 让您以系统的观点看待世界,专注系统的结构信息--全息,抓住事物的本质,透过表象和数据发现规律. 世间每项事物都是一 ...
- 异步编程promise
异步编程发展 异步编程经历了 callback.promise.async/await.generator四个阶段,其中promise和async/await使用最为频繁,而generator因为语法 ...
- 万星开源项目强势回归「GitHub 热点速览 v.22.38」
本周霸榜的 GitHub 项目多为老项目,比如:老面孔的 theatre 凭借极其优秀的动画功底连续三天霸榜 TypeScript 类目.借 Figma 被 Adobe 收购之风,又出现在 GitHu ...
- SQL注入篇——sqli-labs各关卡方法介绍|1-65
主要是记下来了每关通过可以采用的注入方式,可能部分关卡的通关方式写的不全面,欢迎指出,具体的获取数据库信息请手动操作一下. 环境初始界面如下: sql注入流程语句: order by 3--+ #判断 ...
- 【学习笔记】注意力机制(Attention)
前言 这一章看啥视频都不好使,啃书就完事儿了,当然了我也没有感觉自己学的特别扎实,不过好歹是有一定的了解了 注意力机制 由于之前的卷积之类的神经网络,选取卷积中最大的那个数,实际上这种行为是没有目的的 ...
- kvm安装windows使用virtio驱动
Windows安装VirtIO驱动的两种方法 已经使用IDE方式来安装好系统 (1)安装完Windows后,创建一块临时的硬盘和网卡,将其驱动都设置为virtio模式添加到Windows中 (2) 添 ...
- 使用 febootstrap 制作自定义基础镜像
转载自:https://cloud.tencent.com/developer/article/1454524 文章目录1.febootstrap 介绍2.环境.软件准备3.febootstrap 安 ...