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.特点
- 方便,实用的API方法
- 高效的处理方式
- 跨平台
- 更加灵活扩展
- 安全性
二、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的属性列表如下:
属性名 | 类型 | 注解描述 |
---|---|---|
name | String | 指定Servlet 的 name 属性,等价于 。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。 |
value | String[] | 该属性等价于 urlPatterns 属性。两个属性不能同时使用。 |
urlPatterns | String[] | 指定一组 Servlet 的 URL 匹配模式。等价于标签。 |
loadOnStartup | int | 指定 Servlet 的加载顺序,等价于 标签。 |
initParams | WebInitParam[] | 指定一组 Servlet 初始化参数,等价于标签。 |
asyncSupported | boolean | 声明 Servlet 是否支持异步操作模式,等价于 标签。 |
description | String | 该 Servlet 的描述信息,等价于 标签。 |
displayvalue | String | 该 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.匹配顺序
- 精确匹配。
- 路径匹配,先最长路径匹配,再最短路径匹配。
- 扩展名匹配。注意:使用扩展名匹配,前面就不能有任何的路径。
- 缺省匹配,以上都找不到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对象可以完成对客户端的响应工作。
- 设置响应头信息
- 发送状态码
- 设置响应正文
- 重定向
- 响应正文
客户端输出响应正文(响应体)可以使用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);
七、三大域对象
对象名称 | 对象类型 |
---|---|
request | HttpServletRequest |
session | HttpSession |
aplication | ServletContext |
我们可以在域对象中保存一些数据,每个域对象他们都有自己的作用范围。
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;//出错的
匹配规则
- 以指定资源匹配。例如
"/index.jsp"
- 以目录匹配。例如
"/servlet/*"
- 以后缀名匹配,例如
"*.jsp"
- 通配符,拦截所有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