servlet

servlet

一、概念

1.1. 什么是 Servlet

​ servlet 是基于 Jakarta 技术的 Web 组件,由容器管理,可生成动态内容。与其他基于 Jakarta 技术的组件一样,servlet 是独立于平台的 Java 类,它们被编译为与平台无关的字节码,这些字节码可以动态加载到支持 Jakarta 技术的 Web 服务器中并由其运行。容器,有时也称为 servlet 引擎,是提供 servlet 功能的 Web 服务器扩展。Servlet 通过 servlet 容器实现的请求/响应范式与 Web 客户端交互。

从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议Web服务器

1.2. Servlet容器

通常情况下,Servlet容器也就是指Web容器,如Tomcat、Jboss、Resin、WebLogic等,他们来对Servlert进行控制。

请添加图片描述

  • 当Web客户第一次请求访问某个Servlet时,Web容器会创建这个Servlet的实例并放入Servlet实例池。
  • 当Servlet实例化后,容器将调用Servlet对象的init()方法完成Servlet的初始化操作。
  • 容器通过Servlet的service()方法处理客户端请求。
  • Web容器关闭时,容器调用Servlet对象的destroy()方法对资源进行释放。调用此方法后,Servlet对象将被垃圾回收器回收。

1.3.特点

  1. 方便,实用的API方法
  2. 高效的处理方式
  3. 跨平台
  4. 更加灵活扩展
  5. 安全性

二、Servlet的生命周期

2.1.servlet接口

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();//获取Servlet对象的配置信息,返回ServletConfig对象

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();//返回有关Servlet的信息,如作者、版本等

    void destroy();
}
  • init( ),service( ),destroy( )是Servlet生命周期的方法。代表了Servlet从“出生”到“工作”再到“死亡 ”的过程。
(1)init( )方法

当Servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用,就像人只能“出生”一次一样。我们可以利用init()方法来执行相应的初始化工作。调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化。

(2)service( )方法

每当请求Servlet时,Servlet容器就会调用这个方法。就像人一样,需要不停的接受老板的指令并且“工作”。第一次请求时,Servlet容器会先调用init( )方法初始化一个Servlet对象出来,然后会调用它的service( )方法进行工作,但在后续的请求中,Servlet容器只会调用service方法了。

(3)destory()方法

当要销毁Servlet时,Servlet容器就会调用这个方法,就如人一样,到时期了就得死亡。在卸载应用程序或者关闭Servlet容器时,就会发生这种情况,一般在这个方法中会写一些清除代码。

三、创建一个Servlet

1. 实现javax.servlet.Servlet接口。
2. 继承javax.servlet.GenericServlet类
3. 继承javax.servlet.http.HttpServlet类

3.1.配置Servlet的两种方式

  • web.xml配置文件(例如有一个名叫Helloservlet的Servlet的类)
//声明一个Servlet对象
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.lu.HelloServlet</servlet-class>
</servlet>
//映射访问Servlet的URL
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>
  • 使用注解去配置Servlet
@WebServlet(name = "hello3",urlPatterns = "/hello3")
public class HelloServlet3 extends HttpServlet {
...............
}

@WebServlet的属性列表如下:

属性名类型注解描述
nameString指定Servlet 的 name 属性,等价于 。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。
valueString[]该属性等价于 urlPatterns 属性。两个属性不能同时使用。
urlPatternsString[]指定一组 Servlet 的 URL 匹配模式。等价于标签。
loadOnStartupint指定 Servlet 的加载顺序,等价于 标签。
initParamsWebInitParam[]指定一组 Servlet 初始化参数,等价于标签。
asyncSupportedboolean声明 Servlet 是否支持异步操作模式,等价于 标签。
descriptionString该 Servlet 的描述信息,等价于 标签。
displayvalueString该 Servlet 的显示名,通常配合工具使用,等价于 标签。

注意事项

  • web.xml中默认为metadata-complete="true"的话修改其属性为metadata-complete=“false”
  • 不要在web.xml文件中配置该Servlet

3.2.实现Servlet接口

import javax.servlet.*;
import java.io.IOException;
public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
    }
}

3.3继承GenericServlet类

public class test extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        
    }
}
//GenericServlet类中相关方法
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

public void init() throws ServletException {
}
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

3.4继承HttpServlet类

import javax.servlet.http.HttpServlet;

public class test extends HttpServlet {
}

HttpServlet核心方法还是service方法

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();
    long lastModified;
    if (method.equals("GET")) {
        lastModified = this.getLastModified(req);
        if (lastModified == -1L) {
            this.doGet(req, resp);
        } else {
            long ifModifiedSince;
            try {
                ifModifiedSince = req.getDateHeader("If-Modified-Since");
            } catch (IllegalArgumentException var9) {
                ifModifiedSince = -1L;
            }

            if (ifModifiedSince < lastModified / 1000L * 1000L) {
                this.maybeSetLastModified(resp, lastModified);
                this.doGet(req, resp);
            } else {
                resp.setStatus(304);
            }
        }
        .
        .
        .
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String msg = lStrings.getString("http.method_get_not_supported");
    this.sendMethodNotAllowed(req, resp, msg);
}

将来实现类中如果请求是个get请求就重写doGet(),post就重写doPost();

HttpServlet有两个特性是GenericServlet所不具备的:

  • 1.不用覆盖service方法,而是覆盖doGet或者doPost方法。
  • 2.使用的是HttpServletRequest和HttpServletResponse对象。

请添加图片描述

四、servlet的匹配规则

4.1.四种匹配规则

(1) 精确匹配

配置的项必须与url完全精确匹配。

<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
    <url-pattern>/user/hello</url-pattern>
</servlet-mapping>

(2) 路径匹配

以“/”字符开头,并以“/*”结尾的字符串用于路径匹配

<servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/hello2/*</url-pattern>
</servlet-mapping> 

(3)扩展名匹配

以“*.”开头的字符串被用于扩展名匹配

<servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

(4) 缺省匹配

所有路径都将会匹配到这里

<servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

4.2.匹配顺序

  1. 精确匹配。
  2. 路径匹配,先最长路径匹配,再最短路径匹配。
  3. 扩展名匹配。注意:使用扩展名匹配,前面就不能有任何的路径。
  4. 缺省匹配,以上都找不到servlet,就用默认的servlet。

匹配方法只有三种,要么是路径匹配(以“/”字符开头,并以“/”结尾),要么是扩展名匹配(以“.”开 头),要么是精确匹配,三种匹配方法不能进行组合

五、相关接口

5.1.ServletConfig

当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,我们通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

每个Servlet只有一个ServletConfig对象。

public interface ServletConfig {
    String getServletName();  //返回Servlet对象的实例名,xml中配置过name的值

    ServletContext getServletContext();  //获取Servlet上下文对象

    String getInitParameter(String var1);  //String类型名称为name的初始化参数值

    Enumeration<String> getInitParameterNames();  //获取所有初始化参数名的枚举集合
}

ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。

5.2.HttpServletRequest

HttpServletRequest表示Http环境中的Servlet请求。它扩展于javax.servlet.ServletRequest接口,并添加了几个方法。

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

String getContextPath();//返回请求上下文的请求URI部分
Cookie[] getCookies();//返回一个cookie对象数组
String getHeader(String var1);//返回指定HTTP标题的值
String getMethod();//返回生成这个请求HTTP的方法名称
String getQueryString();//返回请求URL中的查询字符串
HttpSession getSession();//返回与这个请求相关的会话对象

请添加图片描述

  • 获取请求行:

获得客户端的请求方式:String getMethod()

获得请求的资源:

String getRequestURI()        //请求地址

StringBuffer getRequestURL()  //请求地址

String getContextPath()       //web应用的名称

String getQueryString()       //get提交url地址后的参数字符串
  • 获取请求头

相关的方法有:

long getDateHeader(String name)

String getHeader(String name)       //获取指定名称的请求头。

Enumeration getHeaderNames()        //获取所有请求头名称。 

Enumeration getHeaders(String name) 

int getIntHeader(String name)       //获取值为int类型的请求头。

  • 获取请求体
String getParameter(String name)           //通过指定名称获取参数值;

String[] getParameterValues(String name)   // 当多个参数名称相同时,可以使用方法来获取;

Enumeration getParameterNames()       //获取所有参数的名字;

Map<String,String[]> getParameterMap() //获取所有参数封装到Map中,其中key为参数名,value为参数值

最为常见的客户端传递参数方式有两种:

浏览器地址栏直接输入:一定是GET请求;

超链接:一定是GET请求;

表单:可以是GET,也可以是POST,这取决与的method属性值;

请求体中的内容是通过post提交的请求参数,格式是:

username=zhangsan&password=123&hobby=football&hobby=basketball

//获取请求参数
String v1 = req.getParameter("p1");
String v2 = req.getParameter("p2");
System.out.println("p1=" + v1);
System.out.println("p2=" + v2);
// 当多个参数名称相同时,可以使用方法来获取;
String[] names = req.getParameterValues("p3");
System.out.println("相同参数名的值为"+Arrays.toString(names));
//获取所有参数的名字;
Enumeration names2 = req.getParameterNames();
while(names2.hasMoreElements()) {
    System.out.println("参数名="+names2.nextElement());
}
//获取所有参数封装到Map中,其中key为参数名,value为参数值,因为一个参数名称可能有多个值,所以参数值是String[],而不是String。
Map<String,String[]> paramMap = req.getParameterMap();
for(String name : paramMap.keySet()) {
    String[] values = paramMap.get(name);
    System.out.println(name + ": " + Arrays.toString(values));
}

另一些方法

getRemoteHost()	//返回发出请求的客户机的完整主机名。
getRemoteAddr()	//返回发出请求的客户机的IP地址。
getPathInfo()	//返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以"/"开头。
getRemotePort()	//返回客户机所使用的网络端口号。
getLocalAddr()	//返回WEB服务器的IP地址。
getLocalName()	//返回WEB服务器的主机名。
  • 请求转发
//在hello2中将转发到hello3的servlet中
System.out.println("我处理了一半工作,另一半需要人帮忙!");
RequestDispatcher requestDispatcher = httpServletRequest.getRequestDispatcher("/hello3");
requestDispatcher.forward(httpServletRequest,httpServletResponse);
  • request域方法

一个请求会创建一个request对象,如果在一个请求中经历了多个Servlet,那么多个Servlet就可以使用 request来共享数据。 下面是request的域方法:

void setAttribute(String name, Object value)  //用来存储一个对象,也可以称之为存储一个域属性,
Object getAttribute(String name)  //用来获取request中的数据,当前在获取之前需要先去存储才行,
void removeAttribute(String name)  //用来移除request中的域属性,如果参数name指定的域属 性不存在,那么本方法什么都不做;
Enumeration getAttributeNames()   //获取所有域属性的名称; 域方法通常在进行重定向时使用,多个servlet共享数据。

5.3.HttpServletResponse

在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。 response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。

  1. 设置响应头信息
  2. 发送状态码
  3. 设置响应正文
  4. 重定向

请添加图片描述

  • 响应正文

客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共 提供了两个响应流对象:

PrintWriter out = response.getWriter():获取字符流,处理字符; 
ServletOutputStream out = response.getOutputStream():获取字节流,处理文件;

不能同时使用这两个流!

在使用response.getWriter()时需要注意默认字符编码为ISO-8859-1,如果希望设置字符流的字 符编码为utf-8,可用response.setCharaceterEncoding(“utf-8”)来设置。这样可以保证输出给客户 端的字符都是使用UTF-8编码的! 但客户端浏览器并不知道响应数据是什么编码的!如果希望通知客户端使用UTF-8来解读响应数据,那么还是使用response.setContentType(“text/html;charset=utf-8”)方法比较好, 因为这个方法不只会调用response.setCharaceterEncoding(“utf-8”),还会设置content-type响应头,客户端浏览器会使用content-type头来解读响应数据。

  • 设置响应头信息

可以使用response对象的setHeader()方法来设置响应头!使用该方法设置的响应头最终会发送给客户端浏览器!

response.setHeader(“content-type”, “text/html;charset=utf-8)  // 设置content-type响应头,该头的作用是告诉浏览器响 应内容为html类型,编码为utf-8。而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”); 
resp.setHeader("refresh","3;URL=http://www.baidu.com");//3秒后自动跳转到百度主页。
  • 设置状态码
 response.setStatus(200)//设置状态码; 
 response.sendError(404, "您要查找的资源不存在");//当发送错误状态码时,Tomcat会跳转到固定的错误页面去,但可以显示错误信息。
  • 重定向

响应码为200表示响应成功,而响应码为302表示重定向。所以完成重定向的第一步就是设置响应码为 302。

因为重定向是通知浏览器再第二个请求,所以浏览器需要知道第二个请求的URL,所以完成重定向的第 二步是设置Location头,指定第二个请求的URL地址。

response.setStatus(302); 
response.setHeader("Location", "http://www.baidu.com");
response.sendRedirect("http://www.baidu.com");//便捷的重定向

如果要重定向的URL是在同一个服务器内,那么可以使用相对路径,例如:

response.sendRedirect("/hello2");// http://localhost:8080/javaweb/hello2

3、重定向和转发的区别

重定向是两次请求,转发是一个请求

重定向是浏览器的行为,请求转发是服务器行为

重定向浏览器的地址会发生改变,转发不会

重定向可以重定向到任何地址,转发只能在项目内转发

所以转发中数据的存取可以用request作用域:request.setAttribute(), request.getAttribute(),重定向是取不到request中的数据的。只能用session

六、sesion和cookie

http是无状态的,他不保存状态,意思就是一个浏览器发的请求,随后就断开了,下一次发送请求就和 上一次无关了。 比如一个用户购买一个商品,第一次需要登录,如果再买一个时向服务器发送请求,服务器如果不知道 是谁发的,那么他就得再登录一次,这显然是不合理的,于是就提出了cookie和session的概念。 cookie是记录在浏览器端的一个字符串,session是保存在服务器端的一个对象。他们两互相配合让服 务器有了能识别客户端一些状态的能力,意思就是服务就就能知道这个客户端有没有登录等。cookie就 相当于通行证,session就是门房,进去时需要从门房识别一个身份。

6.1.cookie

cookie是可以通过key和value构建的,我们可以给他添加一个有效期,单位是秒:

cookie的内容主要包括name(名字)、value(值)、maxAge(失效时间)、path(路径),domain(域)和secure。

//cookie
Cookie cookie = new Cookie("users","123");
httpServletResponse.addCookie(cookie);

maxAge/expires:cookie失效时间,单位秒。如果为正数,则该cookie在maxAge后失效。如果为负数,该cookie为临时cookie,关闭浏览器即失效, 浏览器也不会以任何形式保存该cookie。如果为0,表示删除该cookie。默认为-1

具体的值是过期日期。如果想让cookie的存在期限超过当前浏览器会话时间,就必须使用这个属性。当过了到期日期时,浏览器

就可以删除cookie文件,没有任何影响。

path:该cookie的使用路径。如果设置为"/sessionWeb/",则只有ContextPath为“/sessionWeb/”的程序可以访问该cookie。如果设置为“/”,则本域名下ContextPath都可以访问该cookie。

domain:域,(方法值是域名)可以访问该Cookie的域名。第一个字符必须为".",如果设置为".google.com",则所有以"google.com结尾的域名都可以访问该cookie",如果不设置,则为所有域名。

6.2.session

Session机制是一种服务端的机制,服务器使用一种类似散列表的结构来保存信息。

当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端里的请求里是否已包含了一个session标识–sessionID,如果已经包含一个sessionID,则说明以前已经为此客户端创建过session,服务器就按照sessionID把这个session检索出来使用

如果客户端请求不包含sessionID,则为此客户端创建一个session并且声称一个与此session相关联的sessionID,

sessionID的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串(服务器会自动创建),这个sessionID将被在本次响应中返回给客户端保存。

//true 获取session,如果获取不到就创建
//false 获取session,获取不到就返回null
HttpSession session =  req.getSession(true);

过期时间,默认是30

<session-config>
    <session-timeout>60</session-timeout>
</session-config>

手动添加

String id = session.getId();
Cookie cookie = new Cookie("JSESSIONID",id);
cookie.setMaxAge(1800);
resp.addCookie(cookie);

七、三大域对象

对象名称对象类型
requestHttpServletRequest
sessionHttpSession
aplicationServletContext

我们可以在域对象中保存一些数据,每个域对象他们都有自己的作用范围。

7.1.request

生命周期:

  • 创建:客户端向服务器发送一次请求,服务器就会创建request对象
  • 销毁:服务器对这次请求做出响应后就会销毁request对象
  • 有效:仅当前请求有效

请求转发中传递数据

7.2.session

生命周期:

创建:服务器第一次调用getSession();(保存在服务器中)

销毁:

  • 非正常关闭服务器(正常关闭session会序列化,再次启动服务器session会被反序列化)
  • session过期
  • 手动调用session.invaildate()

注意:关闭浏览器再次访问找不到session的会话id而不是session被销毁

有效:用户打开浏览器会话开始,直到关闭浏览器会话才结束,一次会话期间只会创建一个session对象。

作用:登录状态的保存

7.3.application

生命周期:

  • 创建:服务器启动的时候,服务器为每个web应用创建一个属于该web项目的对象,ServletContext类。
  • 销毁:服务器关闭或者项目从服务器中移除的时候
  • 有效:此信息在整个服务器上被保留

区别:

request 每一次请求都是一个新的request对象,如果在web组件之间需要共享同一个请求中的数据,只能使用请求转发

session每一次会话都是一个新的session对象,如果需要在一次会话中的多个请求之间共享数据只能用session。

application 应用对象,tomcat启动到关闭,表示一个应用,一个应用只有一个application对象,作用于整个web应用,可以实现多次会话之间的数据共享

共同点:

1.设置作用域中的共享数据(保存数据)

作用域对象:setAttribute(String name,Object value)

2.获取作用域中的共享数据(获取数据)

Object value=作用域对象.getAttribute(String name)

3.删除作用域中的指定的共享数据(删除数据)

作用域对象.removeAttribute(String name)

八、过滤器

过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理
通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理

请添加图片描述

应用场景
自动登录
统一设置编码格式
访问权限控制
敏感字符过滤等

实现方式

实现Filter接口

Filter接口如下

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    default void destroy() {
    }
}

在Servlet中我们一般都会对request和response中的字符集编码进行配置,如果Servlet过多字符集编码发生变化时修改起码会很麻烦,这些通用的字符集编码配置等工作我们可以放到Filter中来实现。
下面我们来创建一个处理字符集编码的Filter。

public class HelloFilter implements Filter {
    protected  String encoding = null;
    protected FilterConfig filterConfig = null;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        this.encoding = filterConfig.getInitParameter("encoding");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器中来了");
        if (encoding != null){
            servletRequest.setCharacterEncoding(encoding);
            servletResponse.setContentType("text/html; charset="+encoding);
        }
        filterChain.doFilter(servletRequest,servletResponse);//交给下一个过滤器或servlet处理

    }

    @Override
    public void destroy() {
       this.encoding = null;
       this.filterConfig = null;
    }
}

web.xml文件中配置

<filter>
    <filter-name>filt</filter-name>
    <filter-class>com.lu.Filter.HelloFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>       
        <param-value>GBK</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>filt</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

也可以在类中直接使用 @WebFilter 注解,不再去web,xml中进行配置。

dispatcher
配置拦截的类型,可配置多个。默认为REQUEST
例如

<dispatcher> 。。。</dispatcher>

其中DispatcherType是个枚举类型,有下面几个值

FORWARD,//转发的
INCLUDE,//包含在页面的
REQUEST,//请求的
ASYNC,//异步的
ERROR;//出错的

匹配规则

  1. 以指定资源匹配。例如"/index.jsp"
  2. 以目录匹配。例如"/servlet/*"
  3. 以后缀名匹配,例如"*.jsp"
  4. 通配符,拦截所有web资源。"/*"

过滤器是在服务器启动时就会创建的,只会创建一个实例,常驻内存,也就是说服务器一启动就会执行Filter的init(FilterConfig config)方法.当Filter被移除或服务器正常关闭时,会执行destroy方法

执行顺序

  • 在web.xml中,filter执行顺序跟的顺序有关,先声明的先执行
  • 使用注解配置的话,filter的执行顺序跟名称的字母顺序有关,例如AFilter会比BFilter先执行
  • 如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter

九、监听器

Javaweb中的监听器是用于监听web常见对象HttpServletRequest,HttpSession,ServletContext

1.监听web对象创建与销毁的监听器

ServletContext创建与销毁要监听ServletContextListener

Httpsession的创建与与销毁监听HttpSessionListener

HttpServletRequest创建与销毁监听ServletRequestListener
2.监听web对象属性变化包括属性的(添加,删除,替换(key值一样的时候,调用两次set就会触发这个事件))

ServletContex的属性变化的监听ServletContextAttributeListener

Httpsession的属性变化的监听HttpSessionAttributeListener

HttpServletRequest的属性的变化的监听ServletRequestAttributeListener

3.监听session绑定javaBean(向session中set对象的时候触发)

HttpSessionBindingListener

HttpSessionActivationListener
例:统计网站访问次数

我们可以监听HttpServletRequest的创建

新建一个监听器,实现ServletRequestListener,重写requestInitialized

使用xml或者注解注册到容器中

@WebListener
public class VisitCountListener implements ServletRequestListener {
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        ServletContext application = sre.getServletContext();
        Object count = application.getAttribute("count");
        if (count==null){
            application.setAttribute("count",1);
        }else {
            application.setAttribute("count",(Integer)count+1);
        }
    }
}

web.xml 的加载顺序是:context- param -> listener -> fifilter ->servlet
tRequestAttributeListener

3.监听session绑定javaBean(向session中set对象的时候触发)

HttpSessionBindingListener

HttpSessionActivationListener
例:统计网站访问次数

我们可以监听HttpServletRequest的创建

新建一个监听器,实现ServletRequestListener,重写requestInitialized

使用xml或者注解注册到容器中

@WebListener
public class VisitCountListener implements ServletRequestListener {
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        ServletContext application = sre.getServletContext();
        Object count = application.getAttribute("count");
        if (count==null){
            application.setAttribute("count",1);
        }else {
            application.setAttribute("count",(Integer)count+1);
        }
    }
}

web.xml 的加载顺序是:context- param -> listener -> fifilter ->servlet

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值