代码之家  ›  专栏  ›  技术社区  ›  Madan Madan

基于位置的java Servlet筛选器设置

  •  1
  • Madan Madan  · 技术社区  · 10 年前

    我的应用程序来自不同的国家,我使用一个通用的servlet过滤器(MyFilter.java)来控制所有请求。是否可以根据国家的访问者重定向到其他Servlet? 当前我的web.xml配置如下

     <filter>
        <filter-name>myfilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>myfilter</filter-name>
        <url-pattern>*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    

    假设如果来自美国的用户访问我想将其重定向到US_Filter.java,或者如果来自澳大利亚的用户访问,我想将它重定向到AU_Filter.ava,或者如果用户访问英国,我想把它重定向到UK_Filter.java.这可能来自web.xml吗?

    我正在考虑在web.xml中进行国别配置

    country=US  (US_Filter)
    country=AU  (AU_Filter)
    country=UK  (UK_Filter)
    country=None (MyFilter)
    

    但我不知道怎么做?

    我之所以需要这样做,是因为我们根据国家/地区执行不同的行为,例如,他们的移动无验证、管理用户订阅服务等。

    请给我一些建议。

    谢谢

    2 回复  |  直到 10 年前
        1
  •  2
  •   fps    10 年前

    我认为不可能使用 web.xml 为此。然而,您可以通过编码 MyFilter 类,这样在添加新国家/地区时就不需要修改它。

    我看到你在使用Spring。这是个好消息,因为 我的筛选器 实际上是Spring管理的bean。这意味着可能会向其中注入其他bean。我的建议是,每个国家都有一个bean,并有一个主过滤器负责授权给正确的国家bean。

    首先,让您的 web.xml 如现在所示:

    <filter>
        <filter-name>myfilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>myfilter</filter-name>
        <url-pattern>*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    

    这将使名为 myfilter 为每个请求调用。

    然后,实施 我的筛选器 以这种方式,它是国家不可知的,因此在添加或删除国家时不需要修改:

    @Component("myfilter")
    public class MyFilter implements Filter {
    
        public static final String DEFAULT = "default";
    
        public static final String SUFFIX = "_Filter";
    
        // Autowire all beans that implement CountryFilter, mapped by bean name
        @Autowired
        private Map<String, CountryFilter> filters;
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
    
            // Get country code from request
            Locale locale = request.getLocale();
            String countryCode = locale.getCountry().toUpperCase();
    
            // Format key to gey country-specific filter
            String key = countryCode + SUFFIX;
    
            // If bean doesn't exist for request country...
            if (!this.filters.containsKey(key)) {
                // ..fallback to default filter
                key = DEFAULT + SUFFIX;
            }
    
            // Get filter for country
            CountryFilter filter = this.filters.get(key);
    
            // Delegate to actual country (or default) filter
            boolean countinueChain = filter.doFilterForCountry(request, response);
    
            if (continueChain) {
                chain.doFilter(request, response);
            }
        }
    
        @Override
        public void init(FilterConfig config) throws ServletException {
        }
    
        @Override
        public void destroy() {
        }
    }
    

    这个类足够通用。在添加或删除国家/地区时,您不需要更改它。诀窍是对集合使用Spring自动布线行为。如果自动连线 Map<String, T> ,然后Spring将用类bean的所有实例填充此映射 T ,是与相应bean实例的bean名称和值相等的键。

    那么,你需要 CountryFilter 接口:

    public interface CountryFilter {
    
        boolean doFilterForCountry(ServletRequest request, ServletResponse response) 
            throws IOException, ServletException;
    }
    

    您需要实现 国家过滤器 对于每个国家,让它是一个名称与模式匹配的Spring bean CC_Filter 哪里 CC 代表2位ISO国家代码。例如,对于美国,您可能有:

    @Component("US" + MyFilter.SUFFIX)
    public class UsFilter implements CountryFilter {
    
        @Override
        public boolean doFilterForCountry(ServletRequest request, ServletResponse response) 
            throws IOException, ServletException {
    
            // TODO Handle US specifics here
    
            // VERY IMPORTANT: you might want to let the chain continue...
            return true;
            // ...or redirect to US page
            // ((HttpServletResponse) response).sendRedirect("US-url");
            // return false;
            // ONLY ONE of the options!
        }
    }
    

    对于英国:

    @Component("UK" + MyFilter.SUFFIX)
    public class UkFilter implements CountryFilter {
    
        @Override
        public boolean doFilterForCountry(ServletRequest request, ServletResponse response) 
            throws IOException, ServletException {
    
            // TODO Handle UK specifics here
    
            // VERY IMPORTANT: you might want to let the chain continue...
            return true;
            // ...or redirect to UK page
            // ((HttpServletResponse) response).sendRedirect("UK-url");
            // return false;
            // ONLY ONE of the options!
        }
    }
    

    其他国家也是如此。

    最后,您可能没有针对特定国家的实施。在这种情况下,您可能希望使用默认筛选器作为回退情况:

    @Component(MyFilter.DEFAULT + MyFilter.SUFFIX)
    public class DefaultFilter implements CountryFilter {
    
        @Override
        public boolean doFilterForCountry(ServletRequest request, ServletResponse response) 
            throws IOException, ServletException {
    
            // TODO Handle DEFAULT specifics here
    
            // VERY IMPORTANT: you might want to let the chain continue...
            return true;
            // ...or redirect to DEFAULT page
            // ((HttpServletResponse) response).sendRedirect("DEFAULT-url");
            // return false;
            // ONLY ONE of the options!
        }
    }
    

    希望这能帮助你解决问题。我认为这是一种非常灵活的方法,甚至有一个后备方案。要添加一个新国家,您需要做的就是实施一个新的 国家过滤器 .

        2
  •  0
  •   Abhishek Mungekar    10 年前

    http://examples.javacodegeeks.com/core-java/util/locale/java-util-locale-example/

    请浏览这个网站!!

    使用该站点时,我建议您添加另一个过滤器,以便它检查语言环境;重定向到所需的servlet。