如何在不修改 web.xml 的情况下向 servlet 添加过滤器 [英] How to add filters to servlet without modifying web.xml

查看:39
本文介绍了如何在不修改 web.xml 的情况下向 servlet 添加过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够以不同于 web.xml 的方式修改/配置过滤器.这是 2 个过滤器的静态配置.我希望能够静态配置一个过滤器并允许该过滤器加载其他过滤器.我只是想知道是否有人知道已经有这个的 lib.

I'd like the ability to modify/configure filters in a different way than web.xml. Here is a static configuration of 2 filters. I'd like the ability to have one filter statically configured and allow that filter to load additional filters. I just wanted to know if anyone knows of lib that already has this.

使用 Servlet API 2.5

Using Servlet API 2.5

<web-app>
  ...
  <filter>
    <filter-name>MyFilter1</filter-name>
    <filter-class>com.me.MyFilter1</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter1</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  ...
  <filter>
    <filter-name>MyFilter2</filter-name>
    <filter-class>com.me.MyFilter2</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  ...
</web-app>

我已经看到在 Guice 中使用 GuiceFilter 完成此操作,其中过滤器是在运行时配置的.

I've seen this done in Guice with GuiceFilter where the Filters are configured at runtime.

推荐答案

只需做与容器已经做的相同的工作.IE.重新发明 责任链 设计模式的轮子,就像在幕后使用通过 servlet 过滤器.

Just do the same job as the container already does. I.e. reinvent the wheel of the chain of responsibility design pattern as is under the covers been used by servlet filters.

public class GodFilter implements Filter {

    private Map<Pattern, Filter> filters = new LinkedHashMap<Pattern, Filter>();

    @Override
    public void init(FilterConfig config) throws ServletException {
        Filter1 filter1 = new Filter1();
        filter1.init(config);
        filters.put(new Pattern("/foo/*"), filter1);

        Filter2 filter2 = new Filter2();
        filter2.init(config);
        filters.put(new Pattern("*.bar"), filter2);

        // ...
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest hsr = (HttpServletRequest) request;
        String path = hsr.getRequestURI().substring(hsr.getContextPath().length());
        GodFilterChain godChain = new GodFilterChain(chain);

        for (Entry<Pattern, Filter> entry : filters.entrySet()) {
            if (entry.getKey().matches(path)) {
                godChain.addFilter(entry.getValue());
            }
        }

        godChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        for (Filter filter : filters.values()) {
            filter.destroy();
        }
    }

}

使用那些小的辅助类(如果需要,可以将其设为 private static 上述 GodFilter 的嵌套类):

with those little helper classes (which can if necessary be made private static nested classes of the above GodFilter):

public class Pattern {

    private int position;
    private String url;

    public Pattern(String url) {
        this.position = url.startsWith("*") ? 1
                      : url.endsWith("*") ? -1
                      : 0;
        this.url = url.replaceAll("/?\*", "");
    }

    public boolean matches(String path) {
        return (position == -1) ? path.startsWith(url)
             : (position == 1) ? path.endsWith(url)
             : path.equals(url);
    }

}

public class GodFilterChain implements FilterChain {

    private FilterChain chain;
    private List<Filter> filters = new ArrayList<Filter>();
    private Iterator<Filter> iterator;

    public GodFilterChain(FilterChain chain) {
        this.chain = chain;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        if (iterator == null) {
            iterator = filters.iterator();
        }

        if (iterator.hasNext()) {
            iterator.next().doFilter(request, response, this);
        } else {
            chain.doFilter(request, response);
        }
    }

    public void addFilter(Filter filter) {
        if (iterator != null) {
            throw new IllegalStateException();
        }

        filters.add(filter);
    }

}

如有必要,您还可以提供包含所有可能过滤器的 XML 配置文件,以便您最终获得更简单的配置.您可以使用反射在 GodFilterinit() 中创建过滤器.

You could if necessary also feed a XML config file with all possible filters so that you end up with easier configuration. You could use reflection to create filters in init() of your GodFilter.

哦,没关系,这就是 web.xml 和容器已经在做的......

Oh nevermind, that's what the web.xml and the container already is doing...

这篇关于如何在不修改 web.xml 的情况下向 servlet 添加过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆