java的过滤器

JavaWeb三大组件

1. 都需要在web.xml中进行配置
Servlet
Listener

Filter



2. 过滤器
      它通过web.xml管理着一大片资源,它会在一组资源(jsp、servlet、.css、.html等等)的前面执行!它当你想要访问它管理的资源时,那么它就会拦截进行处理.它可以让请求得到目标资源,也可以不让请求达到!就好比如门卫.  只要是对很多的资源进行操作就应该想到filter



过滤器如何编写

1. 写一个类实现Filter接口
2. 在web.xml中进行配置管理哪些资源

1. Filter接口


1

2

3

4

5

6

    public void doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       System.out.println("filterstart..."); 

       chain.doFilter(request,response);//放行 

       System.out.println("filterend..."); 

    }

void init(FilterConfig)
  * 创建之后,马上执行;Filter会在服务器启动时就创建!
void destory()
  * 销毁之前执行!在服务器关闭时销毁
void doFilter(ServletRequest,ServletResponse,FilterChain)
  * 每次过滤时都会执行

Filter是单例的!和servlet一样

2. web.xml
<filter>
  <filter-name>xxx</filter-name>
  <filter-class>web.filter.AFitler</fitler-class>
</servlet>
<fitler-mapping>
  <filter-name>xxx</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

这个配置代表了这个filter管理哪些资源.访问这些资源时,这个过滤器就会执行doFilter()..



FilterConfig-->与ServletConfig相似
  * 获取初始化参数:getInitParameter()
  * 获取过滤器名称:getFilterName()
  * 获取appliction:getServletContext()

FilterChain(这个用于放行)
  * doFilter(ServletRequest, ServletResponse):放行!
    就相当于调用了目标Servlet的service()方法!

-------------------------------

-------------------------------

多过滤器情况下FilterChain的doFilter()方法:执行目标资源,或是执行下一个过滤器!如果没有下一个过滤器那么执行的是目标资源,如果有,那么就执行下一个过滤器!

-------------------------------

过滤器的四种拦截方式

<dispatcher>REQUEST</dispatcher>默认的!拦截直接请求
  <dispatcher>FORWARD</dispatcher>            拦截请求转发
  <dispatcher>INCLUDE</dispatcher>              拦截请求包含  
  <dispatcher>ERROR</dispatcher>                拦截错误转发

在<filter-mapping>中进行配置!

-------------------------------

多个过滤器的执行顺序

<filter-mapping>的配置顺序决定了过滤器的执行顺序!

过滤器的应用场景:

执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;

通过条件判断是否放行,很多java教程里都这样说的,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;

在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理

实例:

统计IP

循环遍历在ServletContext中的map,其中key是ip地址,value是访问次数

jsp页面


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<body>

<h1>分IP统计访问次数</h1>

<table align="center"width="50%" border="1">

    <tr>

       <th>IP地址</th>

       <th>次数</th>

    </tr>

<c:forEach items="${aplicationScope.ipCountMap}" var="entry">

    <tr>

       <td>${entry.key }</td>

       <td>${entry.value }</td>

    </tr>

</c:forEach>

 </table>  

</body>

filter代码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

public void init(FilterConfig fConfig) throws ServletException {

       context = fConfig.getServletContext();

       Map<String, Integer> ipCountMap = new LinkedHashMap<String, Integer>();

       context.setAttribute("ipCountMap", ipCountMap);

    }

 

  public void doFilter(ServletRequest request, ServletResponseresponse,

           FilterChain chain) throws IOException, ServletException{

       HttpServletRequest req = (HttpServletRequest) request;

       String ip = req.getRemoteAddr();

 

       Map<String, Integer> ipCountMap = (Map<String,Integer>) context

              .getAttribute("ipCountMap");

 

       Integer count = ipCountMap.get(ip);

       if (count == null) {

           count = 1;

       else {

           count += 1;

       }

       ipCountMap.put(ip, count);

 

       context.setAttribute("ipCountMap", ipCountMap);

       chain.doFilter(request, response);

    }

 

    public void destroy() {}

}

解决全站字符乱码

乱码问题:

l  获取请求参数中的乱码问题;

POST请求:request.setCharacterEncoding(“utf-8”);

GET请求:newString(request.getParameter(“xxx”).getBytes(“iso-8859-1”), “utf-8”);

l  响应的乱码问题:response.setContextType(“text/html;charset=utf-8”)。

处理POST请求简单,可是处理get请求需要获取参数,filter获取所有过滤资源的参数是不可能实现的.这里可以调包request再发给servlet.增强request对象(改变getParamater()方法.让每次获取参数时直接解决乱码问题).

增强对象的方式有三种:(对a对象进行增强,fun1()方法)

  1. 继承:  AA类继承a对象的类型:A类,然后重写fun1()方法,其中重写的fun1()方法就是被增强的方法。但是,继承必须要知道a对象的真实类型,然后才能去继承。如果我们不知道a对象的确切类型,而只知道a对象是IA接口的实现类对象,那么就无法使用继承来增强a对象了;
  2. 装饰者模式: AA类去实现a对象相同的接口:IA接口,还需要给AA类传递a对象,AA类所有方法的实现都是调用a对象相同方法实现,只有fun1()方法需要改变下内容,对fun1()进行增强;
  3. 动态代理:和增强者模式比较相似

这里对request对象进行增强是通过继承request对象的装饰类,装饰类是接口的包装类,但是它不进行任何增强,我们通过继承它然后重写需要增强的方法,这样就不用重写需要增强的方法了.

(增强时一看继承类,二看有没有接口的包装类,三接口的装饰者模式)


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

public class EncodingFilter implements Filter {

 public void destroy() {

 }

 public void doFilter(ServletRequest request, ServletResponse response,

   FilterChain chain) throws IOException, ServletException {

  // 处理post请求编码问题

  request.setCharacterEncoding("utf-8");

  

  HttpServletRequest req = (HttpServletRequest) request;

  

  /*

   * 处理GET请求的编码问题

   */

//  String username = request.getParameter("username");

//  username = new String(username.getBytes("ISO-8859-1"), "UTF-8");

  

  /*

   * 调包request

   */

  if(req.getMethod().equals("GET")) {

   EncodingRequest er = new EncodingRequest(req);

   chain.doFilter(er, response);

  else if(req.getMethod().equals("POST")) {

   chain.doFilter(request, response);

  }

 }

 public void init(FilterConfig fConfig) throws ServletException {

 }

}

继承包装类增强request


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/**

 * 装饰reqeust

 */

public class EncodingRequest extends HttpServletRequestWrapper {

 private HttpServletRequest req;

 

 public EncodingRequest(HttpServletRequest request) {

  super(request);

  this.req = request;

 }

 public String getParameter(String name) {

  String value = req.getParameter(name); 

  // 处理编码问题

  try {

   value = new String(value.getBytes("iso-8859-1"), "utf-8");

  catch (UnsupportedEncodingException e) {

   throw new RuntimeException(e);

  

  return value;

 }

}

时间: 2024-08-24 08:04:08

java的过滤器的相关文章

java编码过滤器

1.java编码过滤器的作用: java过滤器能够对目标资源的请求和响应进行截取,过滤信息执行的优先级高于servlet. 它新增加的功能包括:1. 应用程序生命周期事件控制;2. 新的国际化;3. 澄清了类的装载规则;4. 新的错误及安全属性;5. 不赞成使用HttpUtils 类;6. 各种有用的方法;7. 阐明并扩展了几个servlet DTD;8. filter功能. 2.java过滤器的使用: (1)编写一个普通的java类,实现Filter接口 import java.io.IOEx

java中过滤器和监听器详解

先说一下java中过滤器的作用: 过滤器是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url.主要为了减轻服务器负载.减少压力 拦截器的作用: 拦截器是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法.比如可以用拦截器做一些权限管理 或者log之类的事情. 过滤器和拦截器他们的作用是不同的.   Java中过

java web 过滤器跟拦截器的区别和使用

1.首先要明确什么是拦截器.什么是过滤器 1.1 什么是拦截器: 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作.拦截是AOP的一种实现策略. 在Webwork的中文文档的解释为--拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可重用的部分的方式.

Java web--Filter过滤器分IP统计访问次数

分IP统计访问次数即网站统计每个IP地址访问本网站的次数. 分析 因为一个网站可能有多个页面,无论哪个页面被访问,都要统计访问次数,所以使用过滤器最为方便. 因为需要分IP统计,所以可以在过滤器中创建一个Map,使用IP为key,访问次数为value.当有用户访问时,获取请求的IP,如果IP在Map中存在,说明以前访问过,那么在访问次数上加1,即可:IP在Map中不存在,那么设置次数为1. 那么问题来了! 问题一:为什么使用Map存放? Map是一个由键值对组成的数据结构,其中所有的key组成一

java利用过滤器实现编码的转换

在页面建个表单 <form action="login.do" method="post"> <input type="text" name="username" /> <input type="submit" value="确定" /> </form> 建个servlet web.xml <servlet> <servl

java web过滤器

java过滤器(imooc学习)定义:过滤器是一个服务器端的组件,它可以截取用户端的请求与响应信息,并对这些信息过滤. 工作原理 1.过滤器中web容器启动时就进行加载2.过滤器存在于用户请求和web资源之间3.用户请求和web资源响应的[收发]都经过滤器按[过滤规则]进行性过滤 生命周期 实例化-->初始化-->过滤-->销毁web.xml init() doFilter() destroy() web.xml配置 第一个过滤器实例 1.配置web.xml <filter>

Java Web——过滤器

<Java Web开发技术应用——过滤器> 过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上.过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息.在这之后,过滤器可以作如下的选择: ①以常规的方式调用资源(即,调用servlet或JSP页面). ②利用修改过的请求信息调用资源. ③调用资源,但在发送响应到客户机前对其进行修改. ④阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出. 用户请求——>过滤

java中过滤器、监听器、拦截器的区别

1.过滤器:所谓过滤器顾名思义是用来过滤的,在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话).filter 流程是线性的, url传来之后,检查之后,可保持原来的流程

Java 创建过滤器 解析xml文件

今天写了一个过滤器demo,现在是解析actions.xml文件,得到action中的业务规则:不需要导入任何jar包 ActionFilter过滤器类: package accp.com.xh.utils; import java.io.IOException; import java.io.InputStream; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.Filte