过虑器简介:
过虑器能对客户的请求进行预先处理,然后再将请求转发给其他web组件。
过虑器是在Servlet2.3规范中定义的,它可以对Web组件的,ServletRequest和ServletResponse进行检查和修改。
过虑器本身并不生成ServletRequest对象和ServletResponse对象,它只对web组件提供以下过虑功能:
在web组件调用之前检查request,并修改请求头和请求正文。
过虑器能够在web组件被调用之后检查response对像,修改响应头和响应正文。
自定义的过虑器必须实现:javax.servlet.Filter接口。此接口定义了以下三个方法:
Init(FilterConfig conf) – 过虑器的初始化方法。-初始化工作执行一次(启动时)。
doFilter(ServletRequest,ServletResponse,FilterChain) – 此方法完成实际的过虑操作。只要是配置的url匹配此过虑器的配置,即执行此方法。
destroy()-Servlet窗口在销毁过虑器时执行此方法。-销毁工作也只执行一次。
记性不好,简单记录一个demo
web.xml 配置
<filter>
<filter-name>zfx</filter-name>
<filter-class>cn.zfx.filter.ZFXFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>zfx</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher><!-- 默认 -->
</filter-mapping>
/**
* 过滤器
*/
public class ZFXFilter implements Filter{
private String encoding ;
@Override
public void destroy() {
System.out.println("挂了。。。。。。。。。");
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
System.out.println("过滤了。。。。。。。" + encoding);
req.setCharacterEncoding(encoding);
chain.doFilter(req, resp);
System.out.println("后处理过滤了。。。。。。。" + encoding);
}
/**
* 可以读取初始化信息
*/
@Override
public void init(FilterConfig config) throws ServletException {
this.encoding = config.getInitParameter("encoding");
}
}
过滤器可以做很多事情,如:字符集过滤、设置jsp页面不缓存、验证用户是否登录、验证非法字符,其中 request.setCharacterEncoding (“UTF-8”);只可以解决post方式的乱码,不能解决get方式。所以这里可以用包装器模式,包装request,对request增强,java中IO基本都是用的包装设计模式
包装设计模式:
对一个类的增强,一般采取三种式
1、继承被增强的类,即实现一个子类。
2、使用动态代理处理需要增强的方法。
3、使用包装设计模式。(Java中的IO基本上都是包装设计模式)
以下是使用包装设计模式增强一个类的步骤:
1、继承需要增强的类。
2、声明需要增强的类为自己的成员变量。
3、书写一个构造方法接收需要增强的类。
4、实现需要增强的方法。
5、实现可扩展的其他方法。
包装设计模式是指:
假定A类是B类的包装类,那么类A与类B有同样的接口,并且类A拥有类B的的实例,类A借助类B的实例来实现接口。
/**
* 自定义的HttpServletRequest
* 通过实现HttpServletRequestWrapper类
* 实现包装模式
* 用自定义的request实现乱码的解决方案
* 包括get和post
* @author wangjianme
*/
public class MyHttpServletRequest
extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyHttpServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
System.err.println("获取参数。。。。");
String param = request.getParameter(name);
if(param==null){ //如果为空则直接返回
return null;
}
//注意大小写问题
if(request.getMethod().equalsIgnoreCase("GET")){
System.err.println("进行转码");
//如果是get才进行转码,从request中取出编码模式
try {
param = new String(param.getBytes("ISO-8859-1"),request.getCharacterEncoding());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage(),e);
}
return param;
}else{
return param;
}
}
}
/**
* 解决乱码的Filter
* @author wangjianme
*/
public class CharacterFilter implements Filter{
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.err.println("开始过虑。。。。");
request.setCharacterEncoding("UTF-8");
//注意创建自己的request
MyHttpServletRequest req = new MyHttpServletRequest((HttpServletRequest) request);
//注意一下面,一定要传递自己的req对像,否则不好用的
chain.doFilter(req,response);
//以下是没有使用自己的request的,则处理get时必定会出现乱码
//chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}