Filter过滤器 Listener监听
Filter过滤器的使用
1.什么是过滤器?
Filter过滤器它是JavaWEB三大组件之一(Servlet应用程序、Listener监听器、Filter过滤器)
Filter过滤器它是JavaEE的规范,也就是接口。
Filter过滤器它的作用:拦截请求,过滤响应
它会在一组资源(jsp,servlet,.css,.html等)的前面执行
2.过滤器的使用场景
a.防止未登录就进入界面
b.控制应用编码
c.过滤敏感词汇等场景
3.如何编写过滤器?
a.自定义类实现Filter接口,重写接口中的抽象方法(3个)
b.在web.xml中进行配置
<filter>
<filter-name>DemoFilter</filter-name>
<filter-class>com.zking.filter.DemoFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>DemoFilter</filter-name>
<url-pattern>/as.do</url-pattern>
</filter-mapping>
<url-pattern>/a.jsp</url-pattern>:你要拦截的内容是什么?
<url-pattern>/*.jsp</url-pattern>
<url-pattern>/*.do</url-pattern>
<url-pattern>/*</url-pattern>
utils
entity
dao
dao.impl
biz
biz.impl
servlet
filter
listener
4.Filter接口的生命周期
void init(FilterConfig)
* 创建之后,马上执行:Filter会在服务器启动时就创建
void destory()
* 销毁之前执行!在服务器关闭时销毁
void doFilter(ServletRequest,ServletResponse,FilterChain)
* 每次过滤器时都会执行
5.Filter接口中的相关类介绍
FilterConfig---->与ServletConfig相似
* 获取初始化参数:getInitParameter
* 获取过滤器名称:getFilterName
* 获取application:getServletContext
FilterChain
* doFilter(ServletRequest,ServletResponse):放行请求
6.多个过滤器的执行顺序
过滤器的执行顺序和url-pattern标签匹配的精确程度无关,只和他们的filter-mapping标签在web.xml文件中的顺序有关,靠上的配置的先执行。
7.过滤器的四种拦截方式(了解)
REQUEST、FORWARD、INCLUDE、ERROR。
REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;
FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、<jsp:forward>标签都是转发访问;
INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、<jsp:include>标签都是包含访问;
ERROR:当目标资源在web.xml中配置为<error-page>中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。
可以在<filter-mapping>中添加0~n个<dispatcher>子元素,来说明当前访问的拦截方式。
例子:
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/b.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
这个配置中,b.jsp为目标资源。
当直接请求b.jsp时,会执行过滤器。
当转发到b.jsp页面时,会执行过滤器。
1.自动登录
2.解决全站字符乱码(POST和GET中文编码问题)
Filter传给后面Servlet的Request对象肯定不能是原先的,不然request.getParameter()还是会乱码
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// 拦截所有的请求,解决全站中文乱码
// 指定request和response的编码
request.setCharacterEncoding("utf-8");//只对消息体有效
response.setContentType("text/html;charset=utf-8");
// 对request进行包装
CharacterRequest characterRequest = new CharacterRequest(request);
// 放行
chain.doFilter(characterRequest, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
//继承,默认包装类HttpServletRequestWrapper
class CharacterRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public CharacterRequest(HttpServletRequest request) {
super(request);
this.request=request;
}
// 子类继承父类一定会重写一些方法,此处用于重写getParamter()方法
public String getParameter(String name) {
// 调用包装对象的getParameter()方法,获得请求参数
String value = super.getParameter(name);
if(value==null) {
return null;
}
// 判断请求方式
String method = super.getMethod();
if("get".equalsIgnoreCase(method)) {
try {
value = new String(value.getBytes("iso-8859-1"),"utf-8");
}
catch(UnsupportedEncodingException e){
throw new RuntimeException(e);
}
}
// 解决乱码后返回结果
return value;
}