1.写在前面的话
今天JAP君继续给大家讲讲servlet技术,没读过上一篇的朋友,点后面《JavaWeb| 深入servlet技术(一)》,servlet是什么都在上一篇讲过了,所以这里也就不多说了,我们就直接进入主题!
2.Servlet的生命周期
首先,咱们来分析一下“生命周期”这个名词,何谓“生命周期”呢?其实很简单,就是一个东西从创建到销毁的过程。顾名思义,Servlet的生命周期就是Servlet从创建到销毁的过程。
我们接下来就来研究研究Servlet的生命周期,我们一般去研究生命周期都是通过观察它的接口以及里面所要实现的方法,在Servlet接口当中,是有三个方法的:
init(ServletConfig)方法-----------初始化方法
service(ServletRequest,ServletResponse)方法--------每一次我们访问,都会调用来处理请求
destory()方法-----------销毁Servlet的方法
另外,我们还有一个接口---HttpServlet接口(java.servlet.http)
该接口继承自Servlet接口,并重新实现了service()方法,根据不同的请求方式选择不同的处理方法。(doGet()方法和doPost()方法)
从网上找了一张非常易懂的Servlet生命周期的图片,大家可以试着路线走一遍,不对,走两遍,看下两次走的路程是不是相同的。
我们通过代码来实现一遍整个过程
@WebServlet(name = "JAPServlet",urlPatterns = "/demo") public class JAPServlet extends HttpServlet { @Override public void init() throws ServletException { super.init(); System.out.println("init方法被执行了!"); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.service(req, resp); System.out.println("service方法被执行了!"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doGet方法"); } @Override public void destroy() { super.destroy(); System.out.println("destory销毁啦!"); } }
我们先执行一遍-----然后再执行一遍-----然后将服务器关闭,我们来看看输出结果是什么:
init方法被执行了! doGet方法 service方法被执行了! doGet方法 service方法被执行了! E:\tomact\apache-tomcat-9.0.11\bin\catalina.bat stop Using CATALINA_BASE: "C:\Users\lenovo\.IntelliJIdea2018.3\system\tomcat\Tomcat_9_0_11_demo1" Using CATALINA_HOME: "E:\tomact\apache-tomcat-9.0.11" Using CATALINA_TMPDIR: "E:\tomact\apache-tomcat-9.0.11\temp" Using JRE_HOME: "C:\Program Files\Java\jdk1.8.0_171" Using CLASSPATH: "E:\tomact\apache-tomcat-9.0.11\bin\bootstrap.jar;E:\tomact\apache-tomcat-9.0.11\bin\tomcat-juli.jar" 27-Mar-2019 08:16:59.618 信息 [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance. 27-Mar-2019 08:16:59.618 信息 [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-8080"] 27-Mar-2019 08:16:59.942 信息 [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-8009"] 27-Mar-2019 08:17:00.212 信息 [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina] destory销毁啦!
我们可以看到,跟我们的预期是一样的。
注意*:Servlet实例是单例的,也就是说你无论请求多少次Servlet,最多只会有一个Servlet实例,如果是多个客户端并发,同时去访问Servlet的时候服务器会启动多个线程分别执行Servlet的service方法。为什么会这样呢?因为如果我们每一次访问都创建一个Servlet实例,那么会占用很多计算机资源。
3.ServletConfig对象
首先我们来看看ServletConfig对象是个啥?其实懂点英语的都知道Config就是配置的意思,所以ServletConfig对象就是它所对应的Servlet对象的相关配置信息。
ServletConfig对象有些什么特点呢?①每一个ServletConfig都有一个与之对应的Servlet对象。②ServletConfig对象在多个Servlet对象之间是不能共享的。
我们可以在web.xml文件中的<servlet>标签中设置<init-param>标签并且在这个标签里面设置相应的<param-name>和<param-value>。我们设置完后可以通过在Servlet里面调用上面的方法来获取相应的配置信息,由于篇幅有限,这里我就不写代码了,如果有不懂的,可以私聊我。
4.ServletContext-获取项目初始化参数
在上面的ServletConfig中,我们可以通过ServletConfig对象来获取到web.xml中的配置信息,但是当有很多个Servlet时,这样的去获取会非常的麻烦,所以这里我们来介绍一下ServletContext对象。
那么什么是ServletContext对象?字面意思就是Servlet上下文对象,该对象表示当前web的应用环境信息。
我们如何获取ServletContext对象呢?这里有两种方法:①通过ServletConfig的getServletContext()方法可以得到。 ②HttpServlet中直接通过this.getServletContext()获取。
其实ServletContext对象还可以称之为Context域对象,什么是域对象呢?域对象就是在不同资源之间用来共享数据、保存数据、获取数据的。
说了这么多,我们到底怎么来使用它呢?接下来我通过代码给大家实现,首先我们来配置一下web.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <context-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </context-param> </web-app>
从上面可以看到,我们配置了一个<context-param>标签,这样我们就将数据放入到ServletContext对象当中了。
然后我们创建一个servlet,并且在其中的doGet方法中获取ServletContext对象的参数:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String encoding = this.getServletContext().getInitParameter("encoding"); System.out.println(encoding); }
打印出来的结果:
那当我们的context中有多组初始化数据时,我们可以通过ServletContext对象中的getInitParamNames()方法来获取所有的数据
5.ServletContext对象-在多个Servlet之间共享参数
在这个ServletContext对象中有几个方法给大家介绍一下:
我们直接来操作一下吧:我们首先创建两个Servlet文件--“TestServlet1”和“TestServlet2”
我们在TestServlet1中的代码:
@WebServlet(name = "TestServlet1",urlPatterns = "/test2") public class TestServlet1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "JAP君"; this.getServletContext().setAttribute("name",data); } }
再看下TestServlet2中的代码:
@WebServlet(name = "TestServlet2",urlPatterns = "/test2") public class TestServlet2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = (String) this.getServletContext().getAttribute("name"); System.out.println(name); } }
我们分别运行两个servlet,看输出结果:
6.ServletContext-读取项目的资源文件
在web开发中,我们经常需要用到数据库,而数据库是需要有配置信息的,我们怎么去获 取配置信息呢?ServletContext对象里就有很好用的方法。
我们首先创建一个db.properties文件(这个文件对于存储数据库的配置信息很常用)里面内容如下:
url=jdbc:mysql://localhost:3306 name = name passWord = 123
然后我们创建一个Servlet,并在里面写以下内容:
@WebServlet(name = "TestServlet",urlPatterns = "/test") public class TestServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/db.properties"); //读取配置文件 Properties properties = new Properties(); properties.load(resourceAsStream); String name = properties.getProperty("name"); String passWord = properties.getProperty("passWord"); String url = properties.getProperty("url"); System.out.println(name); System.out.println(passWord); System.out.println(url); } }
我们打印出的结果:
我们就拿到了我们想要的数据。这种获取方式是一种固定的模式,大家可以把这几句代码记住,需要用到时就按照这样写。