Filter
Filter:what?
: filter是一个过滤器对象,在开发中,浏览器访问服务端的目标资源的时候,它可以进行拦截功能。
:项目中可以定义多个Filter,filter不仅可以拦截请求,还可以拦截响应过程。
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
filterConfig.getFilterName(); //得到filter的名字
filterConfig.getInitParameter();//得到filter的属性的值
filterConfig.getInitParameterNames();//得到filter的属性的名称
filterConfig.getServletContext();//获取ServletContext对像
chain.doFilter(request,response);//放行的意思,就是不进行拦截
: 在这里面init()方法:过滤器对象的创建,并且初始化。参数有filterConfig,表示对于filter的配置:有上面几种方法。
: doFilter(): servletRequest和serveltResponse是web服务器或filter链的上一个filter发送过来的请求和响应。而参数chain表示filter链的对象,在MyFilter中的dofilter()方法中调用chain.doFilter(request,response)方法,才可以把请求交给下一个filter链中的filter或者是目标程序。
: destory(): 执行拦截后进行销毁。
filter样例编程
MyServlet
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("hello world");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
MyFilter
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletResponse.getWriter().println("hello Filter");
System.out.println("响应过程");
}
@Override
public void destroy() {
}
}
web.xml
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.itcast.chapter.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
<servlet>
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.itcast.chapter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
运行结果:
filter的映射
/*
* : 使用通配符*,拦截所有的客户请求;
: <url-pattern>里进行拦截
: 完全目录匹配:/MyServlet;
: 目录匹配:/*. /aa/*. 表示拦截aa目录下的所有的请求
: 扩展名拦截 : *.do *.jsp 错误的写法:/*.co
* */
filter的请求方式
在配置文件中的,有四个请求方式,默认的是REQUEST,其他FORWARD,INCLUDE,ERROR;
<filter>
<filter-name>MyFilter4</filter-name>
<filter-class>com.itcast.chapter.MyFilter4</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter4</filter-name>
<dispatcher>FORWARD</dispatcher>
<url-pattern>/MyServlet1</url-pattern>
</filter-mapping>
代码:
ForwardServlet:这里面是forward请求,默认的是request请求
public class ForwardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/first.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
ForwardFilter
public class ForwardFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("响应过程");
}
@Override
public void destroy() {
}
}
web.xml
<filter>
<filter-name>ForwardFilter</filter-name>
<filter-class>com.itcast.chapter.ForwardFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ForwardFilter</filter-name>
<url-pattern>/first.jsp</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>ForwardServlet</servlet-name>
<servlet-class>com.itcast.chapter.ForwardServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ForwardServlet</servlet-name>
<url-pattern>/ForwardServlet</url-pattern>
</servlet-mapping>
first.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
hello ForwardServlet!
</body>
</html>
结果是 hello ForwardServlet!
更改:
web.xml
<filter>
<filter-name>ForwardFilter</filter-name>
<filter-class>com.itcast.chapter.ForwardFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ForwardFilter</filter-name>
<url-pattern>/first.jsp</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
结果就不会显示。
filter链
web项目中,注册了多个filter,多个filter程序对同一个url进行拦截,那末这些filter称为filter链。
多个过滤器拦截同一个请求,拦截顺序是安在配置文件中的顺序来的。
代码过程:
:MyServlet
: MyFilter1 拦截MyServlet
: MyFilter2 拦截MyServlet
MyServlet
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("hello world <br>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
MyFilter1
public class MyFilter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletResponse.getWriter().println("hello MyFilter1----- before <br/>");
filterChain.doFilter(servletRequest,servletResponse);
servletResponse.getWriter().println("hello MyFilter1----- after <br/>");
}
@Override
public void destroy() { }
}
MyFilter2
public class MyFilter2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletResponse.getWriter().println("hello MyFilter2----- before <br/>");
filterChain.doFilter(servletRequest,servletResponse);
servletResponse.getWriter().println("hello MyFilter2----- after <br/>");
}
@Override
public void destroy() {
}
}
web.xml
<filter>
<filter-name>MyFilter1</filter-name>
<filter-class>com.itcast.chapter.MyFilter1</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter1</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<filter>
<filter-name>MyFilter2</filter-name>
<filter-class>com.itcast.chapter.MyFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter2</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
结果:注意他们的顺序,1-brfore,2-before而不是1-brfore,1-after.这是chain.doFilter(resquest,response)起的作用,before代表请求,after代表响应过程
filterConfig接口
前面已经提到
代码:
MyFilter3
public class MyFilter3 implements Filter {
String value = "encoding";
FilterConfig filterConfig;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletResponse.getWriter().println(filterConfig.getInitParameter(value));
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
MyServlet3
public class MyServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("hello");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
web.xml
<filter>
<filter-name>MyFilter3</filter-name>
<filter-class>com.itcast.chapter.MyFilter3</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFilter3</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>MyServlet1</servlet-name>
<servlet-class>com.itcast.chapter.MyServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet1</servlet-name>
<url-pattern>/MyServlet1</url-pattern>
</servlet-mapping>
结果是 utf-8
配置属性
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
Listener
what
开发中,可能需要对某些事件进行监听,如监听鼠标点击事件,监听键盘按下事件等,就需要监听器,有四部分组成:
- 事件:用户的一个操作(如点击一个按钮,调用一个方法等)@ 例如早高峰,发生追尾
- 事件源:产生事件的对象 @ 车主A 车主B
- 事件监听器:负责监听发生在事件源上的事件 @ 手机上拍摄的照片或摄像头拍摄的视频
- 事件处理器:监听器的成员方法,当事件发生的时候,会出发对应的处理器 @ 警察根据相应的责任进行处理
- 过程
- 将监听器绑到事件源上,即注册监听器
- 事件发生时,触发监听器的成员方法,即事件处理器,对事件进行处理。
Servlet监听器有8种
- 用来监听域对象的创建于销毁
- 用来监听域对象属性的创建与销毁
- 用来监听HttpSession域对象中对象的状态,即session中保存的对象的状态。
- ServletContextListener:
- HttpSessionListenet
- ServletRequestListener
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
- HttpSessionBindingListener:用于监听JavaBean对象绑定到HttpSession对象和从HttpSession对象解绑的事件
- HttpSessionActivationListener:用于监听HttpSession对象活化和钝化的过程
监听器对象的生命周期
- 通过监听器对象来监听对象的创建和销毁
- 监听器对象:在三个域对象之前进行创建,优先于ServletContext对象之前创建
- ServletContext对象:服务器启动时创建,服务器关闭时销毁
- Session:一次会话开始时创建,会话结束时销毁。销毁:创建默认时间,服务器关闭,调用invalidate方法。
- request对象:请求接受时创建,请求结束时销毁。
监听域对象过程
创建一个MyListener
写一个测试的myjsp.jsp的页面
MyListener
package com.yue.chapter08.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyListener implements ServletContextListener, HttpSessionListener,ServletRequestListener{
public MyListener() {
System.out.println("MyListener被创建,会执行无参构造方法" );
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象被创建");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象被销毁");
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("request请求对象被销毁");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("request请求对象被创建了");
}
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session对象被创建了");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("sesssion对象被销毁了");
}
}
myjsp.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
这是一个测试监听器的页面
<a href="destory.jsp">session对象的销毁方法</a>
</body>
</html>
destory.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<% session.invalidate();%>
</body>
</html>
web.xml
<listener>
<listener-class>com.yue.chapter08.listener.MyListener</listener-class>
</listener>
<session-config>
<session-timeout>2</session-timeout>
</session-config>
监听域对象属性的过程
testattribute.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
session.setAttribute("username","ii");
session.setAttribute("username","aa");
session.removeAttribute("username");
request.setAttribute("username","ii");
request.setAttribute("username","aa");
request.removeAttribute("username");
%>
</body>
</html>
MyAttributeListener
public class MyAttributeListener implements ServletContextAttributeListener,HttpSessionAttributeListener, ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
}
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
String name = servletRequestAttributeEvent.getName();
System.out.println("ServletRequest添加属性:" +name+"="+servletRequestAttributeEvent.getServletRequest().getParameter("name"));
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
String name = servletRequestAttributeEvent.getName();
System.out.println("ServletRequest替换属性:" +name+"="+servletRequestAttributeEvent.getServletRequest().getParameter("name"));
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
String name = servletRequestAttributeEvent.getName();
System.out.println("ServletRequest移除属性:" +name);
}
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
String name = httpSessionBindingEvent.getName();
System.out.println("httpSession添加属性:" + name +"="+httpSessionBindingEvent.getSession().getAttribute(name) );
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
String name = httpSessionBindingEvent.getName();
System.out.println("httpSession移除属性:" + name );
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
String name = httpSessionBindingEvent.getName();
System.out.println("httpSession替换属性:" + name +"="+httpSessionBindingEvent.getSession().getAttribute(name) );
}
}
web.xml
<listener>
<listener-class>com.yue.chapter08.attribute.MyAttributeListener</listener-class>
</listener>
开发中,监听域对象属性用到的较多。