• Servlet过滤器与封装器


    1.过滤器

      在容器调用Servlet的service()方法前,Servlet并不知道有请求的到来,在Servlet的service()方法执行后,容器真正对浏览器进行响应之前,浏览器也不知道Servlet真正的响应是什么。过滤器正如其名所示,可以拦截过滤浏览器对Servlet的请求,也可以改变Servlet对浏览器的响应。

      要实现过滤器,必须实现Filter接口,并在web.xml中定义过滤器。Filter接口有三个要实现的方法:init(),doFilter(),destroy()。

      FilterConfig为web.xml中过滤器的代表对象,如果在定义过滤器时设置了初始参数,可以通过getInitParameter()方法取得初始参数。

      当请求来到容器,容器发现在调用Servlet的service()方法之前可以应用某个过滤器时,会调用该过滤器的doFilter()方法。如果调用了FilterChain的doFilter()方法,就会执行下一个过滤器,直至目标Servlet的service()方法。如果因为某些情况(例如未通过用户验证)而没有调用FilterChain的doFilter(),则请求不会继续交给接下来的过滤器或目标Servlet,这既是拦截请求。

      在陆续调用玩Filter实例的doFilter()至Servlet的service()之后,流程会以堆栈顺序返回,所以在FilterChain的doFilter()之后,可以针对service()做后续处理。

      //service()前置处理

      chain.doFilter(request, response);

      //service()后置处理

    import java.io.*;
    import javax.servlet.*;

    public class PerformanceFilter implements Filter {
    private FilterConfig filterConfig;
    public void init(FilterConfig filterConfig) throws ServletException {
    this.filterConfig = filterConfig;
    }

    public void doFilter(ServletRequest request,
    ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    long begin = System.currentTimeMillis();
    chain.doFilter(request, response);
    filterConfig.getServletContext().log("Request process in " +
    (System.currentTimeMillis() - begin) + " milliseconds");
    }

    public void destroy() {

    }
    }

      在web.xml中设置过滤器时,<filter-mapping>中可以使用<url-pattern>来指定哪些url请求将应用此过滤器,也可以使用<servlet-name>指定哪些Servlet将应用此过滤器。触发过滤器的时机,默认是浏览器直接发出请求。如果是那些通过设置RequestDispatcher的forward()或include()的请求,则可以在web.xml中设置<dispatcher>标签,指定哪些请求转发类型将触发过滤器。如果某个url或者Servlet会应用多个过滤器,则根据<filter-ampping>在web.xml中出现的先后顺序决定过滤器的执行顺序。

    2.封装器

      对于容器产生的HttpServletRequest对象,我们无法直接修改某些信息,比如请求参数。可以通过继承HttpServletRequestWrapper类,并重写某些方法。对于HttpServletResponse对象,可以继承HttpServletResponseWrapper类。

    import java.util.*;
    import javax.servlet.http.*;
    import javax.servlet.http.HttpServletRequestWrapper;

    public class CharacterRequestWrapper extends HttpServletRequestWrapper {

    private Map<String, String> escapeMap;

    public CharacterRequestWrapper(HttpServletRequest request,
    Map<String, String> escapeMap) {
    super(request);
    this.escapeMap = escapeMap;
    }

    @Override
    public String getParameter(String name) {
    return doEscape(this.getRequest().getParameter(name));
    }



    private String doEscape(String parameter) {
    String result = parameter;
    Iterator<String> iterator = escapeMap.keySet().iterator();
    while (iterator.hasNext()) {
    String origin = iterator.next();
    String escape = escapeMap.get(origin);
    result = result.replaceAll(origin, escape);
    }

    return result;
    }
    }

    使用这个请求封装器类搭配过滤器,可以进行字符过滤的服务。

    import java.io.*;
    import java.util.*;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.servlet.*;
    import javax.servlet.http.*;

    public class CharacterFilter implements Filter {
    private Map<String, String> escapeMap;

    public void init(FilterConfig filterConfig)
    throws ServletException {
    BufferedReader reader = null;
    try {
    String escapeListFile = filterConfig
    .getInitParameter("ESCAPE_LIST");
    reader = new BufferedReader(
    new InputStreamReader(
    filterConfig.getServletContext()
    .getResourceAsStream(escapeListFile)));
    String input = null;
    escapeMap = new HashMap<String, String>();
    while ((input = reader.readLine()) != null) {
    String[] tokens = input.split("\t");
    escapeMap.put(tokens[0], tokens[1]);
    }
    } catch (IOException ex) {
    Logger.getLogger(CharacterFilter.class.getName())
    .log(Level.SEVERE, null, ex);
    }
    finally {
    try {
    reader.close();
    } catch (IOException ex) {
    Logger.getLogger(CharacterFilter.class.getName())
    .log(Level.SEVERE, null, ex);
    }
    }
    }

    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {
    HttpServletRequest requestWrapper =
    new CharacterRequestWrapper(
    (HttpServletRequest) request, escapeMap);
    chain.doFilter(requestWrapper, response);
    }

    public void destroy() {
    }
    }




     

  • 相关阅读:
    Ado.Net Entity Framework 批量删除、判断存在
    Asp.Net MVC 3 与 HTML 5
    Entity SQL 时间条件比较
    Visual Studio 2010 调试 C 语言程序
    XAML 属性设置Windows Phone笔记
    SQL Server 2008 R2 数据库之间的数据同步热备份
    SQL Server 2008 R2 SP1正式版发布
    一个 Windows Form Demo
    PL SQL 9 安装 并连接 64位 Oracle 11G
    转载:如何稳定地使用 Google 搜索
  • 原文地址:https://www.cnblogs.com/liuping/p/2223635.html
Copyright © 2020-2023  润新知