过滤器
过滤器(Filter)是J2EE Servlet模块下的组件,作用是对URI进行统一拦截处理。Filter通常用于应用程序层面进行请求的前置处理
过滤链
Filter开发
开发过滤器三要素:
- 任何过滤器都要实现
javax.servlet.Filter
接口 - 在Filter接口的doFilter()方法中编写过滤器的功能代码
public class FirstFilter implements Filter {
/**
* 初始化
*
* @param filterConfig
* @throws ServletException
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 代码处理核心
*
* @param servletRequest 请求
* @param servletResponse 响应
* @param filterChain 过滤链
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器已生成");
// 将请求响应向后传递,被后续的Filter或者Servlet进行处理
filterChain.doFilter(servletRequest, servletResponse);
}
/**
* 销毁方法
*/
@Override
public void destroy() {
}
}
- 在web.xml中对过滤器进行配置,定义拦截URI的范围
<filter>
<filter-name>firstFilter</filter-name>
<filter-class>pers.hua.filter.FirstFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>firstFilter</filter-name>
<!-- /* 对所有URI进行过滤 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器声明周期
会随着服务器启动时进行初始化,服务器关闭或重启是进行销毁。
过滤器的特性
过滤器对象在Web应用启动时被创建且全剧唯一
唯一的过滤器对象在并发环境中采用“多线程”提供服务
Filter应用实践
WebFilter注解使用
代码语言:javascript复制@WebFilter(filterName = "annotationFilter", urlPatterns = {"/*"})
public class AnnotationFilter implements Filter {
...
}
配置与注解如何选择
- 配置形式维护性更好,适合应用全局过滤
- 注解形式开发体验更好,适合小型项目敏捷开发
字符集过滤器
- GET请求 - servlet.xml 增加
URIEncoding=“UTF-8”
- POST请求 - 使用
request.setCharacterEncoding(“UTF-8”)
- 响应 -
response.setContentType(“text/html;charset=utf-8”)
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
// 设置POST请求字符集
req.setCharacterEncoding("utf-8");
// 设置响应体字符集
resp.setContentType("text/html;charset=UTF-8");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
参数化过滤器
代码语言:javascript复制过滤器为了增强灵活性,允许配置信息放在web.xml。在web.xml中配置
<init-param>
设置过滤器参数
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>pers.hua.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
代码语言:javascript复制public class CharacterEncodingFilter implements Filter {
private String encoding;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 获取web.xml配置中的init-param名称
encoding = filterConfig.getInitParameter("encoding");
System.out.println("Encoding:" encoding);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
// 设置POST请求字符集
req.setCharacterEncoding(encoding);
// 设置响应体字符集
resp.setContentType("text/html;charset=" encoding);
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
多参数,添加多次init-param
注解形式
代码语言:javascript复制@WebFilter(filterName = "acef", urlPatterns = "/*",
initParams = {
@WebInitParam(name = "encoding", value = "UTF-8"),
@WebInitParam(name = "name1", value = "value1"),
@WebInitParam(name = "name2", value = "value2")
}
)
url-pattern常用写法
/index.html
- 执行资源精准匹配/servlet/*
- 以前缀进行模糊匹配*.html
- 以后缀进行模糊匹配
/与/*的区别
/
应用在Servlet配置,使该Servlet替代主页
/*
应用在过滤器,代表对所有请求拦截
过滤链
- 每一个过滤器应具有单独职能
- 过滤器的执行顺序以
<filter-mapping>
为准 - 调用chain.doFilter()将请求向后传递
多端设备自动匹配
代码语言:javascript复制public class DeviceAdapterFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
// 获取URI 移动端:index.html => 自动转为 /mobile/index.html || PC端:index.html => /desktop/index.html
String uri = req.getRequestURI();
// 获取请求头
String userAgent = req.getHeader("User-Agent");
String targetURL = null;
// startsWith 当字符串以什么什么开始的时候,做什么后续护理
if (uri.startsWith("/desktop") || uri.startsWith("/mobile")){
filterChain.doFilter(servletRequest, servletResponse);
}else {
if (userAgent.toLowerCase().indexOf("android") != -1 || userAgent.toLowerCase().indexOf("iphone") != -1) {
targetURL = "/mobile" uri;
System.out.println("移动端正在访问:" targetURL);
} else {
targetURL = "/desktop" uri;
System.out.println("PC端正在访问:" targetURL);
}
resp.sendRedirect(targetURL);
}
}
@Override
public void destroy() {
}
}
监听器-Listener
监听器(LIstener)是J2EE Servlet模块下的组件,对Web应用对象行为进行监控。通过Listener监听自动除法指定的功能代码
过滤器与监听器的区别
过滤器(Filter)的职责是对URL进行过滤拦截,是主动执行
监听器(Listener)的职责是对Web对象行为监听,是被动触发