本帖最后由 htb52110 于 2017-12-15 22:36 编辑
Listener&Filter
1、监听器:
概念:
监听器:就是一个Java类,用来监听其他的JAva的状态的变化
作用:
用来监听其他的对象的变化的
主要应用在图形化界面中比较多
GUI android
术语:
事件源:指的是被监听的对象
监听器:指的是监听的对象
事件源与监听器的绑定:
事件:指的是事件源的改变。
2、WEB中的监听器
分为三类八种(监听三个域对象)
事件源:Servlet中的三个域对象
监听器:自定义类实现8个接口
事件源和监听器的绑定:配置
2.1、WEB中的监听器的分类
三类八种:
一类:监听三个域对象的创建和销毁的监听器:
ServletContextListener
HttpSessionListener
ServletRequestListener
二类:监听三个域对象的属性变更的监听器(属性添加,移除,替换):
ServletContextAttributeListener
HttpSessionAttributeListener
ServletRequestAttributeListener
三类:监听HttpSession中的JavaBean的状态改变(绑定,解除绑定,钝化,活化)
HttpSessionBindingListener
HttpSessionActivationListener
2.1.1、 ServletContextListener:监听ServletContext对象的创建和销毁:
2.1.1.1、方法:
2.1.1.2、ServletContext对象何时创建和销毁
创建:服务器启动的时候,服务器为每个WEB应用创建一个属于该web项目的对 象ServletContext.
销毁:服务器关闭或者项目从服务器中移除的时候.
2.1.1.3、企业中的应用:
加载框架的配置文件 :Spring框架 ContextLoaderListener
定时任务调度: : Timer TimerTask
2.1.2、HttpSessionListener:监听HttpSession的创建和销毁的监听器:
2.1.2.1、方法:
2.1.2.2、HttpSession何时创建和销毁的
创建:
服务器端第一次调用getSession();
销毁:
非正常关闭服务器(正常关闭session会序列化):
session过期了默认30分钟.
手动调用session.invalidate();
2.1.2.3、HttpSession的问题
访问Servlet会不会创建Session : 不会
访问JSP会不会创建Session :会.
访问html会不会创建Session :不会
2.1.3、 ServletRequestListener:监听ServletRequest对象的创建和销毁的监听器:
2.1.3.1、方法:
2.1.3.2、request对象何时创建和销毁
创建:客户端向服务器发送一次请求,服务器就会创建request对象.
销毁:服务器对这次请求作出响应后就会销毁request对象.
2.1.3.3、问题
访问一个Servlet会不会创建request对象:会
访问一个JSP会不会创建request对象:会
访问一个HTML会不会创建request对象:会
2.2.1、 ServletContextAttributeListener:监听ServletContext对象的属性变更:
2.2.1.1、方法:
2.2.2、 HttpSessionAttributeListener:监听HttpSession中的属性变更:
2.2.2.1、方法:
2.2.3、 ServletRequestAttributeListener:监听ServletRequest对象的属性变更的:
2.2.3.1、方法:
2.3.1、 HttpSessionBindingListener:监听HttpSession中的JavaBean的绑定和解除绑定的
2.3.1.1、方法:
2.3.2、HttpSessionActivationListener:监听HttpSession中的JavaBean的钝化和活化的.
2.3.2.1、方法:
2.3.2.2、
sessionDidActivate(); :--活化(反序列化)
sessionWillPassivate(); :--钝化(序列化到硬盘)
2.3.2.3、 优化Session:
* 通过配置<Context>标签配置定时session序列化.
* 在tomcat/conf/context.xml中配置<Context> :在tomcat中所有的虚拟主机和虚拟路径都会按照这个配置执行.
* 在tomcat/conf/Catalina/localhost/context.xml配置<Context> :在tomcat中的localhost虚拟主机中的所有虚拟路径按照这个配置执行.
* 在当前的工程下的META-INF/context.xml配置<Context> :当前这个工程按照配置执行.
配置文件:
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>
注意:第三类监听器很特殊,,不需要进行配置的.作用在JavaBean上的监听器.JavaBean可以自己感知到在Session中的状态.
3、Filter
3.1、Filter的概念
可以过滤从客户端想服务器发送的请求。
3.2、Filter的用途
进行IP的过滤,脏话过滤,自动登录,权限的分配,响应压缩。。。
3.3、使用过滤器
a、新建一个类,实现Filter的接口
b、在web.xml里进行配置,形式和servlet的配置信息类似
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>com.itheima.filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/demo1.jsp</url-pattern>
(路径里边具体路径就是对该路径进行过滤,所有请求过滤写【/*】)
</filter-mapping>
3.3、过滤器的生命周期
3.3.1、过滤器的创建和销毁
创建:服务器启动的时候创建过滤器对象
销毁:服务器关闭的时候,或者项目移出的时候。
3.3.2、FilterConfig过滤器的配置对象
3.4、FilterChain过滤器链
过滤器链中的过滤器的执行的顺序与<filter-mapping>的配置顺序有关.
FilterChain doFilter(request,response); 放行,放行到下一个过滤器,如果没有下一个过滤器,到大目标资源
3.5、Filter相关的配置
3.5.1、 <url-pattern>的配置(拦截的路径):
完全路径匹配 :以 / 开始 /demo4/demo1.jsp
目录匹配 : 以 / 开始 以 * 结束. /* /demo1/*
扩展名匹配 :不能以 / 开始 以 * 开始. *.do *.action
3.5.2、 <servlet-name>的配置:
根据Servlet的名称拦截Servlet.
3.5.3、 <dispatcher>的配置(拦截的方式):
* REQUEST :默认值.
* FORWARD :转发.
* INCLUDE : 包含.
* ERROR : 错误页面跳转.(全局错误页面)
3.6、增强Request中的getparameter方法
继承 :控制这个类构造.
装饰者模式 :增强的类和被增强类实现相同的接口,增强的类中获得到被增强的类的引用.
* 缺点:接口中方法太多.
动态代理 :被增强的类实现接口就可以.
附件:利用装饰者模式进行增强Request中的getparameter()方法的代码demo
package cn.itcast.demo6;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* 解决get和post请求 全部乱码
*
* @author 姜涛
*
*/
public class GenericEncodingFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 转型为与协议相关对象
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 对request包装增强
HttpServletRequest myrequest = new MyRequest(httpServletRequest);
chain.doFilter(myrequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
// 自定义request对象
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
private boolean hasEncode;
public MyRequest(HttpServletRequest request) {
super(request);// super必须写
this.request = request;
}
// 对需要增强方法 进行覆盖
@Override
public Map getParameterMap() {
// 先获得请求方式
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
// post请求
try {
// 处理post乱码
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {
// get请求
Map<String, String[]> parameterMap = request.getParameterMap();
if (!hasEncode) { // 确保get手动编码逻辑只运行一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
// 处理get乱码
values = new String(values
.getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0]; // 取回参数的第一个值
}
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
} |
|