JavaWeb09-Servlet(Java真正的全栈开发)

时间:2022-05-04
本文章向大家介绍JavaWeb09-Servlet(Java真正的全栈开发),主要内容包括Servlet、一.Servlet、二.ServletConfig接口、三.ServletContext接口、四.Classpath 文件路径、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

Servlet

一.Servlet

1. servlet介绍

Servlet 是在服务器上运行的小程序。Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。(它可以做css和html做的所有)这个过程为如图:

a. 客户端发送请求至服务器端;

b. 服务器将请求信息发送至 Servlet;

c. Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;

d. 服务器将响应返回给客户端。

一个 Servlet 就是 Java语言中的一个类,它被用来扩展服务器的性能,服务器上驻留着可以通过“请求-响应”编程模型来访问的应用程序。虽然 Servlet 可以对任何类型的请求产生响应,但通常只用来扩展 Web 服务器的应用程序。

我们通过tomcat上提供的案例来看下servlet的写法:

如图:

启动tomcat服务器,访问examples工程,查看其下的servlets。

点击Servlets examples,我们可以看到下图

查看一个示例,例如Hello World这个示例。

这是Hello World这个示例的源代码,我们可以很清楚的知道,servlet其实就是一个java类,这个类继承了HttpServlet,注意,HttpServlet是java servlet api下的一个类,它不在我们的jdk中,所以使用时我们需要单独导入这个jar包,我们可以在tomcat中的lib下找到这个包.

路径: ***apache-tomcat-7.0.42libservlet-api.jar

那么我们在浏览器上输入一个路径后,怎样就可以访问到这个servlet呢?

我们来查看examples这个工程的配置文件web.xml,在这个文件中有下面这段内容:

<servlet>

<servlet-name>HelloWorldExample</servlet-name>

<servlet-class>HelloWorldExample</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>HelloWorldExample</servlet-name>

<url-pattern>/servlets/servlet/HelloWorldExample</url-pattern>

</servlet-mapping>

其实这段内容就是对我们访问的HelloWorld这个servlet在tomcat服务器上的一个配置路径,简单说,当我们访问 http://localhost:8080/examples/servlets/servlet/HelloWorldExample时,就会通过<url-pattern>映射的路径查找到对应的servlet 类。

编写servlet步骤

1.编写一个类(servlet)

2.编写配置文件(项目下/web-inf/web.xml)

2. servlet入门案例

通过上面的分析,我们接下来自己完成一个servlet的入门案例

1.在myeclipse中创建一个web project

注意:因为我们使用的是myeclipse这个”神器”,当我们创建一个web project时,会自动帮助我们导入javaee的libraries,所以不需要在手动导入servlet api.如果我们是纯手动创建,那么就需要自己导入servlet api.

2.创建一个java类 HelloWorldServlet

3.编写代码重写doget,dopost方法

package cn.itcast.a_helloworldservlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

publicclassHelloWorldServletextends HttpServlet {//继承httpservlet

//重写doGet方法

publicvoid doGet(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException {

System.out.println("hello world servlet");

}

}

4.配置web.xml文件

<servlet>

<servlet-name>HelloWorldServlet</servlet-name>

<servlet-class>cn.itcast.a_helloworldservlet.HelloWorldServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>HelloWorldServlet</servlet-name>

<url-pattern>/hello</url-pattern>

</servlet-mapping>

<!--

(1)注册servlet 通过servlet标签

常用的子标签

<servlet-name>:给自己的servlet起个名字 名字自定义 唯一

<servlet-class>:全限定名(包名+类名) com.mysql.jdbc.Driver 一般采用复制的方式

<!--

<servlet>

<servlet-name>HelloServlet111</servlet-name>

<servlet-class>cn.itcast.a_hello.HelloServlet</servlet-class>

</servlet>

-->

(2)绑定路径 通过servlet-mapping标签

常用的子标签

<servlet-name>:使用已注册好的名字 复制上面的名字

<url-pattern>:自己编写的路径 目前以"/"开头 例如 :/hello 唯一的

<!--

<servlet-mapping>

<servlet-name>HelloServlet111</servlet-name>

<url-pattern>/hello</url-pattern>

</servlet-mapping>

-->

5.访问servlet

将工程部署到tomcat中,并启动tomcat。在浏览器中访问 http://localhost/day08/hello

http://端口号/项目名/绑定路径

我们在控制台上就可以看到结果

6.创建servlet步骤总结

通过上述的操作,我们就完成了一个简单的servlet创建,那么我们总结一下:

对于一个servlet来说,我们要创建它的步骤如下:

1.创建一个类,继承HttpServlet

2.重写doGet(和doPost)方法

3.在web.xml文件中配置servlet。

7.servlet执行流程

1.浏览器发送请求

2.服务器接受请求,封住对象,查找web.xml 将封装的信息发送给对应的servlet

3.servlet处理业务逻辑,然后生成动态内容 发送给服务器

4.服务器接受到servlet的内容之后,...,最终将结果返回给浏览器

5.浏览器解析接受到的内容

3. Servlet体系结构与api详解

通过上面的入门案例,我们知道了怎样创建及访问一个servlet,Servlet是一个接口,那么我们接下来深入了解一下servlet。

HttpServlet抽象类

HttpServlet的常用方法:

service(ServletRequest,ServletResponse):服务

将接受的两个参数强转成子类

servletrequest==>HttpServletRequest

ServletResponse==>HttpServletResponse

调用了自己重载的service(HttpServletRequest,HttpServletResponse)

service(HttpServletRequest,HttpServletResponse):重载的方法

判断请求方式,调用相应的doXxx()

doGet(HttpServletRequest,HttpServletResponse):处理get请求的

doPost(HttpServletRequest,HttpServletResponse):处理post请求的

Javax.servlet.http.HttpServlet类,是一个抽象类,它的作用是提供将要被子类以创建适用于web 站点的Http servlet的抽象类。而对于HttpServlet的子类,一般需要重写以下方法。

doGet,如果 servlet 支持 HTTP GET 请求

doPost,用于 HTTP POST 请求

init 和 destroy,用于管理 servlet 的生命周期内保存的资源

getServletInfo,servlet 使用它提供有关其自身的信息

我们在操作中一般重写doPost或doGet方法就可以。

通过API查询,我们会发现HttpServlet有一个父类,GenericServlet.

GenericServletd抽象类

GenericServlet的常用方法:

除了service方法没有实现,其他四个都实现了

init(ServletConfig):继承过来的 将config赋值给成员 调用了无参的init()

以后需要重写初始化方法的时候只需要重写无参的init方法即可

这个类是HttpServlet的父类,它也是一个抽象类,它主要是处理一般的,与协议无关的servlet,如果,要编写关于http协议请使用HttpServlet。

对于我们创建一个servlet,也可以直接继承GenericServlet,虽然这种方式不常见,但也是创建servlet的一种方式。

对于GenericServlet,它实现了一个Servlet接口,这个接口定义了所有的servlet都必须实现的方法。

Servlet接口

servlet的常用方法:

void init(ServletConfig config):初始化方法

void service(ServletRequest request,ServletResponse response):服务 处理业务逻辑

void destroy():销毁

ServletConfig getServletConfig():获取该servlet的配置对象

定义所有 servlet 都必须实现的方法。

servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。

要实现此接口,可以编写一个扩展 javax.servlet.GenericServlet 的一般 servlet,或者编写一个扩展 javax.servlet.http.HttpServlet 的 HTTP servlet。

此接口定义了初始化 servlet 的方法、为请求提供服务的方法和从服务器移除 servlet 的方法。这些方法称为生命周期方法,它们是按以下顺序调用的:

Servlet调用顺序:

1.构造 servlet,然后使用 init 方法将其初始化。

2.处理来自客户端的对 service 方法的所有调用。

3.从服务中取出 servlet,然后使用 destroy 方法销毁它,最后进行垃圾回收并终止它。

除了生命周期方法之外,此接口还提供了 getServletConfig 方法和 getServletInfo 方法,servlet 可使用前一种方法获得任何启动信息,而后一种方法允许 servlet 返回有关其自身的基本信息,比如作者、版本和版权。

接下来,我们通过一个图来将上述内容总结一下:

4. servlet生命周期

void init(ServletConfig config):初始化方法

* init:初始化方法

* 执行时机:默认第一次访问的时候

* 执行次数:一次

* 执行者:服务器

void service(ServletRequest request,ServletResponse response):服务 处理业务逻辑

* service:服务 处理业务逻辑

* 执行时机:访问来的时候

* 执行次数:访问一次执行一次

* 执行者:服务器

void destroy():销毁

* destroy:销毁

* 执行时机:当该servlet被移除的时候或者服务器正常关闭的时候

* 执行次数:一次

* 执行者:服务器

面试题:描述一下servlet的生命周期

servlet是一个单实例多线程的.

默认当第一次请求来的时候,服务器调用init方法实现初始化操作,然后调用一下service方法

每接受一次请求,创建一个线程,服务器调用service方法

当该servlet被移除的时候或者是服务器正常关闭的时候调用destroy方法 执行销毁操作.

为什么编写一个servlet继承了httpservlet并且重写doget,dopost方法

我们自己编写一个servlet继承了httpservlet

我们的servlet有什么方法

service(ServletRequest,ServletResponse):

强转ServletRequest,ServletResponse调用下面的方法

service(HttpServletRequest,HttpServletResponse)

判断请求方式 调用doget,dopost方法

doXxx(HttpServletRequest,HttpServletResponse)

调用自己重写的doXxx方法

加载和实例化 Servlet。这项操作一般是动态执行的。然而,Server 通常会提供一个管理的选项,用于在 服务器启动时强制装载和初始化特定的 Servlet。

Server 创建一个 Servlet的实例

第一个客户端的请求到达服务器

服务器调用 Servlet 的 init() 方法(可配置为 服务器 创建 Servlet 实例时调用,在 web.xml 中 <servlet> 标签下配置 <load-on-startup> 标签,配置的值为整型,值越小 Servlet 的启动优先级越高)

一个客户端的请求到达 服务器, 服务器实例化一个 Servlet的实例

服务器创建一个请求对象,处理客户端请求

服务器创建一个响应对象,响应客户端请求

服务器激活 Servlet 的 service() 方法,传递请求和响应对象作为参数

service() 方法获得关于请求对象的信息,处理请求,访问其他资源,获得需要的信息

service() 方法使用响应对象的方法,将响应传回Server,最终到达客户端。service()方法可能激活其它方法以处理请求,如 doGet() 或 doPost() 或程序员自己开发的新的方法。

对于更多的客户端请求,服务器创建新的请求和响应对象,仍然激活此 Servlet 的 service() 方法,将这两个对象作为参数传递给它。如此重复以上的循环,但无需再次调用 init() 方法。一般 Servlet 只初始化一次(只有一个对象),当 服务器不再需要 Servlet 时(一般当 服务器关闭时),服务器 调用 Servlet 的 destroy() 方法。

简单描述如下:

1.客户端请求该 Servlet;

2.加载 Servlet 类到内存;

3.实例化、初始化该 Servlet;

4.init() 初始化参数;

5.service()(doGet() 或者 doPost());

6.destroy()。

示例代码如下:

注意:我们在重写init方法是,不需要重写带参数的,只需要重写无参数的init方法就可以。

原因: 在GenericServlet中已经将有参数的init方法重写,并调用了一个无参数的init,所以我们在重写时,不需要在重写有参数init方法

5. url-pattern配置

我们在创建servlet后,如果想要这个servlet可以被我们访问到,必须在web.xml文件中对其进行配置。

在其中有一个<url-pattern>这个标签是用于确定我们访问一个servlet的路径,接下来,我们详细介绍一下关于这个标签的配置

<url-pattern>它是用于确定我们访问一个servlet的路径.

一个servlet可以被不同的路径映射,换句话说多个不同配置可以映射同一个servlet.我们可以通过下面的示例来说明上面的问题

上面是关于Demo1Servlet的配置,大家发现我们对于Demo1Servlet它有两个<servlet-mapping>与其映射,那么这时当我们访问

http://localhost/day08/demo1

http://localhost/day08/hellodemo1

时都可以访问到Demo1Servlet.

那么对于<url-pattern>我们在值的写法到底应该怎样处理哪?

对于<url-pattern>我们在开发中它的写法有以下几种:

完全匹配:必须以"/"开始 例如:/a/b/hello

目录匹配:必须以"/"开始 以"*"结尾 例如: /a/*

后缀名匹配: *.xxx 例如: *.do *.jsp

当自己的项目中没有对象servlet的时候,会查找服务器的web.xml,

当我们访问的路径不存在的时候,是服务器里面的默认servlet做的 (defaultServlet)

优先级问题:

优先级 完全匹配>目录匹配>扩展名匹配

练习:

有如下的一些映射关系:

Servlet1 映射到 /abc/*

Servlet2 映射到 /*

Servlet3 映射到 /abc

Servlet4 映射到 *.do

问题:

当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应

Servlet引擎将调用Servlet1。

当请求URL为“/abc”时,“/*”和“/abc”都匹配,哪个servlet响应

Servlet引擎将调用Servlet3。

当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应

Servlet引擎将调用Servlet1。

当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应

Servlet引擎将调用Servlet2.

当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应

Servlet引擎将调用Servlet2。

我们现在查看几个例子,我们找到tomcat/conf/web.xml ,在这个文件中配置的所有内容,其实是被我们自己的工程中的web.xml文件继承了,在这个配置文件中有以下几段内容:

对于这段配置,只要访问时后缀名是jsp或jspx就会执行名称叫jsp的servlet内容,这是一个很典型的扩展名匹配效果

在tomcat/conf/web.xml中还有这样一段配置

注意:这时<url-pattern>它的值就是”/”那么这时它就是一个默认(缺省)的servlet.。

默认的servlet其作用是用于处理其它的servlet处理不了的请求。

6. load-on-startup修改初始化时机

作用:修改当前servlet的初始化时机

<load-on-startup>正整数</...>

值越小 优先级越高

有值以后,随着服务器的启动而调用该servlet的init(..)方法

上面我们提到过<load-on-startup>,它可以让我们在服务器实例化servlet时就调用这个servlet,简单说就是可以让一个servlet可以在服务器启动时,就加载这个servlet。我们以LifeServlet类为例来说明一下。

Servlet的配置

我们在<servlet>标签中添加了一个<load-on-startup>,它的值为2,那么这时LifeServlet就会在服务器启动时,跟随启动。

注意:<load-on-startup>的值越小代表的是优先级越高。

7. servlet模版修改

我们通过myeclipse创建servlet时,会发现在java文件上有很多注释,并且在servlet请求处理方法内也有很多代码,那么我们是否可以在创建一个servlet时,让代码简洁一些哪,这时我们就可以修改myeclipse中的servlet模板。

具体操作:

a. 关闭myeclipse,在mycelipse安装目录下查找到common/plugins目录 ,在其目录下找到

b. com.genuitec.eclipse.wizards_9.0.0.me201211011550.jar这个文件

c. 使用解压工具将其打开

d. 将其中templates/Servlet.java复制出来

e. 进行修改

f. 重新将Servlet.java copy回去

g. 重新启动myeclipse,创建servlet

8. 客户端访问servlet路径问题

1.访问一个资源的方法

1.地址栏输入

2.超链接 a href

3.form action属性

4.location.href属性

5.window.open()

2.路径的写法:(从浏览器端到服务器端)

1.绝对路径

带协议和主机的绝对路径

例如: http://www.itcast.cn

http://localhost:8080/web/12123123

不带协议和主机的绝对路径 ☆

例如: /项目名称/访问的资源路径

http://localhost/day09/hello

/day09/hello

2.相对路径

./ 当前目录

../ 上一级目录

八字分针

当前路径: http://localhost/day09/ a.html ./c/d/b.html

访问路径: http://localhost/day09/ c/d/b.html

当前路径: http://localhost/day09/ e/a.html ../c/d/b.html

访问路径: http://localhost/day09/ c/d/b.html

我们在开发中,经常在页面上通过表单或超连接向服务器发送请求,如果我们访问的是一个servlet,那么这时访问servlet的路径应该如何书写?接下来我们就介绍一下,关于在客户端访问servlet的路径问题.

在介绍之前,我们先看一下,现阶段我们有多少种方式可以访问服务器端的一个资源

在地址栏上直接输入url

超连接的方式

通过表单方式

通过js的location.href方式

通过js的window.open()方法

对于以上方式,只有表单提交的方式才可能有POST请求,其它的都是GET请求。

下面我们通过示例来说明一下关于在客户端访问servlet的路径问题:

1.创建一个Demo2Servlet

2.在WebRoot下创建demo2.html页面

以上操作,访问到demo2servlet时在控制台上输出了get请求访问。

3.在WebRoot下创建一个目录main,将demo2.html文件赋值到main目录下在次访问

http://localhost/day08/main/demo2.html

这时我们在访问时,绝对路径是不会出现问题的,但是当访问相对路径时,页面上报出了404,代表找不到资源。

我们分析一下原因:

相对路径,是指我们的servlet访问路径与当前的页面之间的一个相对关系。

那么我们的servlet访问路径是 http://localhost/day08/demo2

而我们访问main/demo2.html的路径是 http://localhost/day08/main/demo2.html

这时通过路径对比我们发现demo2.html的路径与demo2的路径它们之间不是在一个层次下,如果想要访问到,可以修改成以下结果:

这时,在次访问,会发现访问成功。

结论:

对于我们后续的学习与开发中,我们使用绝对路径会比较多一些,而在使用绝对路径时,我们主要使用的是不带协议的绝对路径,而带协议的绝对路径只要在访问站外资源时才会使用。对于相对路径,我们需要分析它们的相对关系,所以不建议大家使用。

二.ServletConfig接口

1. servletConfig介绍和作用

ServletConfig是javax.servlet包下的一个接口,它是由servlet容器(tomcat)创建,并封装了servlet相关配置信息的对象,并在servlet容器初始化期间传递给了servlet. 通过init(ServletConfig config)方法传递。

关于有参数init(ServletConfig config)与无参数init()方法关系:

有参数的init方法,是servlet接口中定义的。

而无参数的init方法是GenericServlet中定义的。

在GenericServlet中重写了有参数的init方法,并在其中调用了无参数的init方法。

那么,我们在创建一个servlet时,如果是继承了HttpServlet,在重写init方法时,

就可以只重写无参数init就可以。

2. 获取servletConfig

对于ServletConfig对象,我们在自己的servlet中如果想要获取到,可以通过getServletConfig()对象来获取。这个方法是在javax.servlet.Servlet接口中定义的,在GenericServlet中对getServletConfig()方法进行了实现。在servlet中以过下面代码就可以获取ServletConfig对象。

ServletConfig config=this.getServletConfig();

3. servletConfig的api详解

String getServletName()

获取在web应用程序中部署的servlet实例的名称(servletName中定义的)

String getInitParameter(String name)

获取指定初始化参数的值,如果不存在,返回null

Enumeration getInitParameterNames()

以 String 对象的 Enumeration 的形式返回 servlet 的初始化参数的名称

ServletContext getServletContext()

返回对调用者在其中执行操作的 ServletContext 的引用(获取servlet的管理者)。

4.总结+用法

ServletConfig作用三个方面:

获取Servlet名称 getServletName()

获取Servlet初始化参数 getInitParameter() getInitParameterNames()

获取ServletContext对象{获取全局管理者(上下文)}

获取ServletConfig:

getServletConfig()

常用方法:

String getServletName():获取当前servlet的名称

String getInitParameters("参数名称"):获取单一的参数

Enumeration getInitParameterNames();获取所有的参数名称

ServletContext getServletContext():获取全局的管理者

什么是Servlet初始化参数:

在web.xml文件中我们可以对servlet进行配置,在<servlet>配置标签内可以有以下这样的子标签 init-param (初始化参数的位置 在servlet标签下 init-param)

<init-param>
<param-name>参数名称</param-name>
<param-value>参数值</param-value>
</init-param>

这就是用于声明servlet的初始化参数

servletConfig的产生:

当服务器创建servlet的时候,同时创建该servlet的配置对象(servletConfig),

然后通过servlet的init(servletConfig),将创建的servletConfig传递给当前servlet

在genericServlet的init方法中,将传递来的servletconfig赋给了成员

三.ServletContext接口

1. servletContext的介绍和作用

ServletContext它是javax.servlet.包下的一个接口。本质上就是当前项目的引用

WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。

结论:

它代表的是web应用上下文

获取context=this.getServletConfig().getServletContext();

在开发中可以通过以下方式获取

ServletContext context=this.getServletContext();

在getServletContext()方法内部也是通过ServletContext ServletConfig获取的。

1.ServlectContext作用:

获取全局初始化参数

实现servlet共享资源(servlet之间通信)

获取web资源

其它操作

2.获取servletcontext的方式:

方式1:

getServletConfig().getServletContext() (了解)

方式2:

getServletContext(); ☆

2.servletContext常用方法介绍:

1.servletContext获取初始化参数

在web.xml文件中有<context-param>标签可以设置全局初始化参数.

(全局初始化参数的位置: 是在根节点下)

<context-param>
<param-name>encoding</param-name> encoding编码
<param-value>utf-8</param-value>
</co ntext-param>

获取初始化参数

String getInitParameter(String name "参数名称" );获取单一的参数

Enumeration getInitParameterNames(); 获取所有的参数名称

2.servletContext获取资源案例

String getRealPath(String path) 获取文件的路径(在服务器上的路径)

例如:

getRealPath("/"):获取项目的根目录(在服务器)Ø

//获取5.txt的路径

String path= context.getRealPath(“/5.txt”);

System.out.println(path);

InputStream getResourceAsStream(“文件的路径”) 以流的形式返回文件(在服务器上路径)

//获取5.txt的内容

InputSteam is = context.getReasourceAsSteam(“/5.txt”);

System.out.println(new BufferedReader(new InputSteamReader(is)).readLine());

3其他作用

String getMimeType(String file) 可以获取一个文件的mimeType类型.

例如:text/html text/css text/javascript image/jpg 大类型/小类形

//获取mime类型

String type = context.getMimeType(“/1.html”);

System.out.println(type);

URL getResource(String path) 它返回的是一个资源的URL

log(String msg),getRequestDispatcher(String path) 方法,可以做日志与转向操作

4.servletContext实现servlet共享数据(域对象)

ServletContext对于一个web应用只有一个,所有的servlet使用的就是同一个ServletContext。

域对象:

ServletContext

看成一个map

//获取域对象

ServletContext context = this.getServletContext();

(1)ServletContext方法:

void setAttribute(String name,Object object) 设置值 (key,value)形式

将对象绑定到此 servlet 上下文中的给定属性名称。如果已将指定名称用于某个属性,则此方法将使用新属性替换具有该名称的属性。

//设置值

context.setAttribute(“arr”,new int[]{1,2,3});u

Object getAttribute(String name) 获取值 (key)

返回具有给定名称的 servlet 容器属性,如果不具有该名称的属性,则返回 null。

//获取值

Int[] arr =(int[] context.getAttribute(“arr”));

System.out.println(Arrays.toString(arr));

void removeAttribute(String name) 移除值 (key)

从 servlet 上下文中移除具有给定名称的属性。

//移除值

context.removeAttribute(“arr”);

(2)servletcontext的生命周期:

当前项目的应用,当项目启动的时候创建servletcontext

当项目移除的时候或者服务器关闭的时候销毁servletContext

案例:统计访问站点的人数

做一个VisitServlet用于记录次数

做一个ShowCountServlet用于显示次数

做一个CountServlet用于记录次数

package web.servlet;
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 CountServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* 记录当前servlet被访问的次数 先获取值 判断一下 设置值
*/
// 获取Servletcontext
ServletContext context = this.getServletContext();
// 获取访问次数
Integer count = (Integer) context.getAttribute("count");
// 判断次数
if (count == null) {
count = 1;
} else {
count++;
}
// 设置次数
context.setAttribute("count", count);
System.out.println("被访问.........");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}

做一个ShowServlet用于显示次数

package web.servlet;
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 ShowServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/**
* 展示servlet被访问的次数 首先获取访问次数
*
*/
// 1.获取域对象
ServletContext context = this.getServletContext();
// 2.获取访问次数
Integer count = (Integer) context.getAttribute("count");
// 3.打印
System.out.println("countServlet被访问的次数为:" +( count == null ? 0 : count));
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}

四.Classpath 文件路径

java project----所有class都在bin目录下

web project-----所有的class都在classes目录下

1. Class获取(通过字节码文件获取)

Class.getResource("").getPath();获取的是当前Class对象代表的类所在的包的路径。(当前字节码文件所在路径)(到了包下面)

Class.getResource("/").getPath();获取classes目录的绝对磁盘路径(字节码文件根目录)

2. ClassLoader获取(通过类加载器获取)

Class.getClassLoader().getResource("").getPath();

获取的是classes目录的绝对磁盘路径(字节码文件根目录)

Class.getClassLoader().getResource("/").getPath();

获取的是classes目录的绝对磁盘路径(字节码文件根目录)

这两个getResource()是使用当前ClassLoader加载资源(即资源在 Class path中),这样资源和class直接打在jar包中,避免文件路径问题.两者不同是Class的getResource()方法是从当前.class 文件路径查找资源,ClassLoader则是从jar包根目录查找.。

案例-获取资源

需求:在web工程中创建四个txt文件,并在文件中任意写入内容。

文件名

项目中

Tomact下

使用方法

1.txt

src目录

tomcat/webapps/项目名/WEB-INF/classes

四种方法classpath三种之一

2.txt

WebRoot目录

tomcat/webapps/项目名(根目录)

getrealpath

3.txt

WEB-IN目录

tomcat/webapps/项目名/WEB-INF

getrealpath

4.txt

src/cn/itcast/工程的根目录(包下)

tomcat/webapps/项目名/WEB-INF/classes/cn/itcast

5种方法 获取当前字节码文件的方法

1.txt A.class.getClassLoader().getResource(“/1.txt”).getPath();

2.txt this.getServletContext().getRealPath(“/2.txt”)

3.txt this.getServletContext().getRealPath(“/WEB-INF/3.txt”)

4.txt A.class.getClassLoader().getResource(“/cn/itcast/4.txt”).getPath()

A.class.getResource(“4.txt”).getPath()

在Servlet中将这些txt文件中的内容读取出来,打印到控制台。