servlet过滤器

来源:互联网 发布:软件开发技术风险 编辑:程序博客网 时间:2024/05/01 19:13

Web应用中可以使用过滤器对所有的访问和请求进行统一的处理、IP访问限制以及用户发送请求的字符编码转换等,在进行具体的业务逻辑处理之前,首先要经过过滤器的同意处理,然后才开始进入真正的逻辑处理阶段。

过滤器的基本原理

过滤器的功能就是在服务器和酷虎中间增加了一个中间层,可以对两者之间的交互进行统一的处理,每一个从客户端提交的请求都需要通过过滤器的处理然后再进行其他操作。

在实际开发过程中,过滤器可以用来对用户进行统一的身份判断、IP访问限制、用户发送请求的字符编码转换、对请求和响应进行加密和解密、记录用户登录日志等。当然过滤的用途不仅仅这些,我们可以根据过滤器的实现原理,思考过滤器的更多用途。

IP访问filter

在实际应用中,可能会遇到这样的情况,需要对某些IP进行访问限制,不让非法的IP访问应用系统,这个时候就需要用到过滤器进行限制,当一个用户发出访问请求的时候,首先通过过滤器进行判断,如果用户的IP地址被限制,就禁止访问,只有合法的IP才可能继续访问。

代码:

package com.foxmail.xxy668;import java.io.IOException;import java.io.PrintWriter;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 com.sun.net.httpserver.Filter.Chain;public class IPFilter implements Filter {protected FilterConfig fiterConfig;protected String ip;@Overridepublic void destroy() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {String remoteIP=request.getRemoteAddr();if(remoteIP.equals(ip)){response.setCharacterEncoding("gb2312");PrintWriter out=response.getWriter();out.println("<br>your IP is forbid!<br>");}else{chain.doFilter(request,response);}}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {this.fiterConfig=filterConfig;this.ip=this.fiterConfig.getInitParameter("ip");}}

代码解析:

在上面这个过滤器中,主要的方法就是initdoFilter这两个方法,init方法是一个过滤器初始化的时候调用的,在这个过滤器中初始化的工作就是从配置文件中读取参数的内容;而doFilter方法的功能就是这个过滤器真正要执行的处理功能,在这个示例程序中,对IP的限制就是在这个方法中实现的。

1、第29行取得用户访问系统的用户的IP地址。

2if判断中是对比用户IP和禁止访问的IP,如果一致则不允许访问反之允许访问。

 

转换字符编码filter

Java语言中,默认的编码方式是ISO-8859-1,这种编码格式不支持中文的显示,我们可以用类似<%@page contentTpye=”text/html;charset=gb2312”%>这样的方式来规定页面字符编码格式,但是如果要显示的内容是表单提交奥或者是经过Servlet处理,这时候字符内容本身的编码格式就是ISO-8859-1,所以尽管页面指定的字符编码方案为GB2312中文内容仍然不能正常显示。见博客

代码:

package com.foxmail.xxy668;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;public class SetCharacterEncodingFilter implements Filter{protected FilterConfig filterConfig;protected String encodingName;protected boolean enable;@Overridepublic void destroy() {// TODO Auto-generated method stub}public SetCharacterEncodingFilter() {this.encodingName="gb2312";this.enable=false;}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {if(this.enable){request.setCharacterEncoding(this.encodingName);}chain.doFilter(request,response);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {this.filterConfig=filterConfig;loadConfigParams();}private void loadConfigParams(){this.encodingName=this.filterConfig.getInitParameter("encoding");String strIgnoreFlag=this.filterConfig.getInitParameter("enable");if(strIgnoreFlag.equalsIgnoreCase("true")){this.enable=true;}else{this.enable=false;}}}

代码解析:

在上面的这个过滤器中,init方法从配置文件中取出字符编码格式的参数,在doFilter方法中使用request对象对所有的请求统一编码格式。

 

个人感觉过滤器有点像设计模式中的外观,又有点像职责连。

和外观相似的的是:无论什么请求先交由过滤器处理,然后才进行其他操作。这里体现了单一职责原则,过滤器只负责过滤,其他操作交由后面的类进行处理,如果没有过滤器那么字符集的设置会出现在每一个Servlet中,导致职责不单一,代码冗余。

像职责连模式相似的是:每个过滤器在进行完自己的“过滤”工作之后交由下一个过滤器处理,直到没有过滤器为止。这里体现了迪米特法则,工作如果是一步一步来得那么第一步干完之后不必直到第三步甚至后面需要做什么,他只需要直到第二步就可以了,降低耦合。

原创粉丝点击