Web应用中Filter的定义和使用

web开发中,客户端发来请求时,可以对请求和回应信息进行过滤,或者说对RequestResponse进行拦截。比如对数据编码,加解密,验证用户合法性,过滤垃圾数据等。

 

定义过滤器类

必须实现 java.servlet.Filter接口  

实现三个方法:

1、init(FilterConfigfilterConfig) 初始化过滤器,在Servlet容器启动时(一般为tomcat启动时)创建Filter实例的时候就会调用该方法,所以如果修改了其中的内容,需要重启tomcat才行。多用于读取web.xml文件中Servlet过滤器的初始化参数。

                                                                        

2、doFilter(ServletRequest request,ServletResponseresponse,FilterChain chain)  进行过滤处理,所有过滤处理都在这个方法中实现

处理完毕,需要调用chain.doFilter(request,response)方法,把请求继续向后传递,可以是对下一个过滤器doFilter方法的调用,或者相应的web组件。所以Filter采用了职责链设计模式。

然后继续在这等着其他请求,类似于Servletservice()

 

3、destroy() 过滤器销毁  Servlet容器在销毁过滤器实例之前该方法得到调用,以释放占用的资源。

 

设置字符集

response

页面中文显示:

<%@ page language="java"contentType="text/html; charset=GB18030"

 

使用PrintWriter输出中文

response.setContentType("text/xml;charset=utf-8");

 

request

否则,每个Servlet或者JSP都需要设置request字符集,例如

// 设置request字符集(文件头设置response字符集)

         request.setCharacterEncoding("GB18030");

 

原理图


 

CharsetEncodingFilter.java

 

public class CharsetEncodingFilter implements Filter {
 
 //设置默认的字符集,避免忘了配置Filter文件设置字符集导致出现乱码
private String encoding = "UTF-8";
 
@Override
public void doFilter(ServletRequest request, ServletResponseresponse,
FilterChain chain) throws IOException, ServletException {
 
// 设置字符集
//                request.setCharacterEncoding("GBK");
request.setCharacterEncoding(encoding);
 
// 继续执行
chain.doFilter(request, response);
}
 
@Override
public void init(FilterConfig filterConfig) throwsServletException {
//从配置文件中CharsetEncodingFilter的init-param中取值,如果没有的话就使用默认的
encoding = filterConfig.getInitParameter("encoding");
}
 
@Override
public void destroy() {
 
}
}


 

web.xml

 

<filter>
<filter-name>CharsetEncodingFilter</filter-name>
<filter-class>com.java.drp.util.filter.CharsetEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharsetEncodingFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CharsetEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>

 


防止url跳转,判断用户是否已登录

AuthFilter.java

 

		public class AuthFilter implements Filter {
		
			@Override
			public void destroy() {
			}
		
			@Override
			public void doFilter(ServletRequest request, ServletResponse response,
					FilterChain chain) throws IOException, ServletException {
				
				HttpServletRequest req = (HttpServletRequest)request;
				HttpServletResponse resp = (HttpServletResponse)response;
				
				// /DRP6.3/login.jsp
				String reqURI = req.getRequestURI();
				// 截取字符串,得到/login.jsp
				String subReqURI = reqURI.substring(reqURI.indexOf("/", 1), reqURI.length());
				
				// 如果是登陆页或者验证码的servlet,继续执行;否则进行验证
				if (!"/login.jsp".equals(subReqURI) && !"/servlet/util/AuthImageServlet".equals(subReqURI)) {
					// 如果用户没有登录,则跳到登陆页
					HttpSession session = req.getSession(false);
					if (session == null || session.getAttribute("user_info") == null) {
						resp.sendRedirect(req.getContextPath() + "/login.jsp");
						return;
					}
				}
				// 继续执行
				chain.doFilter(request, response);
			}
		
			@Override
			public void init(FilterConfig arg0) throws ServletException {
				
			}
		
		}


web.xml

 

		<filter>
			<filter-name>AuthFilter</filter-name>
			<filter-class>com.java.drp.util.filter.AuthFilter</filter-class>
		</filter>
		<filter-mapping>
			<filter-name>AuthFilter</filter-name>
			<url-pattern>*.jsp</url-pattern>
		</filter-mapping>
		<filter-mapping>
			<filter-name>AuthFilter</filter-name>
			<url-pattern>/servlet/*</url-pattern>
		</filter-mapping>


//改善登陆页:当session过期,子页面跳出框架,变成登陆页

if(window.self != window.top){

//用当前窗口位置引用覆盖顶层窗口位置引用,使得没有父亲引用

window.top.location = window.self.location;

}

 

Web Cache

对于在一定时间内不变的图片或者js文件等,无需每次请求都重新加载,而是放在缓存中。

还可以使用第三方产品 OSCache

 

WebCacheFilter.java

 

publicclass WebCacheFilter implements Filter {
 
@Override
publicvoid destroy() {
 
}
 
@Override
publicvoid doFilter(ServletRequest req, ServletResponse resp,
FilterChainchain) throws IOException, ServletException {
 
HttpServletRequestrequest = (HttpServletRequest)req;
HttpServletResponseresponse = (HttpServletResponse)resp;
 
//设置Cache-control
response.setHeader("Cache-control","max-age=5000");
//继续执行
chain.doFilter(request,response);
}
 
@Override
publicvoid init(FilterConfig arg0) throws ServletException {
 
}
}



web.xml

 

<filter>
<filter-name>WebCacheFilter</filter-name>
<filter-class>com.java.drp.util.filter.WebCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>WebCacheFilter</filter-name>
<url-pattern>*.gif</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>WebCacheFilter</filter-name>
<url-pattern>*.jpg</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>WebCacheFilter</filter-name>
<url-pattern>*.png</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>WebCacheFilter</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>WebCacheFilter</filter-name>
<url-pattern>*.css</url-pattern>
</filter-mapping>



分析特点

  • 只对post请求起作用,而页面默认是get请求,所以想通过filter需要显示声明method
  • 责任链,多个filter,后进先出
  • 生命周期类似servlet,只实例化一次,然后等待。
  • AOPAspect-Oriented Programming)面向切面编程,是一种横切性的技术
  • 提供一种声明式服务,具有可插拔能力。

 

原文地址:https://www.cnblogs.com/javawebsoa/p/3069802.html