java Servlet过滤器基于位置的设置

Posted

技术标签:

【中文标题】java Servlet过滤器基于位置的设置【英文标题】:java Servlet Filter Location based settings 【发布时间】:2015-05-13 03:02:33 【问题描述】:

我的应用程序是从不同的国家访问的,我正在使用一个通用的 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.java,或者如果来自英国的用户访问我想将其重定向到 UK_Filter.java .这可能来自 web.xml 吗?

我正在考虑在 web.xml 中进行国家/地区明智的配置,例如

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

但我不知道怎么做?

我要求这样做是因为我们根据国家/地区执行的不同行为,例如他们的手机没有验证、管理用户订阅服务等。

请给我一些建议。

谢谢,

【问题讨论】:

网址中有国家吗?您可以通过 url 模式在 web.xml 中映射过滤器。否则,您需要在 MyFilter 中执行您想要的逻辑。 在 URL 中我不能有国家,但 jsp 可以将它作为参数传递。如何将这些映射到 web.xml 文件中? 您不会在web.xml 文件中映射它,而是在您的过滤器中,使用代码。 @Magnamag。但这会像任何时候引入新国家一样产生影响,我必须继续更改此过滤器。 我明白了。我将发布一个可以实现您想要的答案。问题:您想重定向到基于国家/地区的过滤器还是基于国家/地区的 servlet? 【参考方案1】:

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

请浏览本站!!

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

【讨论】:

使用该站点,我建议您添加另一个过滤器,以便它检查区域设置并重定向到所需的 servlet。【参考方案2】:

我认为不可能为此使用您的web.xml。但是,您可以通过仔细编码 MyFilter 类来完成您想要的,这样您在添加新国家/地区时就不需要修改它。

我看到您正在使用 Spring。这是个好消息,因为MyFilter 实际上是一个由 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 的 bean 为每个请求调用。

然后,以与国家/地区无关的方式实施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&lt;String, T&gt;,那么Spring 将使用类T 的所有bean 实例填充此映射,它们是与bean 名称和值对应的bean 实例相同的键。

那么,你需要CountryFilter 接口:

public interface CountryFilter 

    boolean doFilterForCountry(ServletRequest request, ServletResponse response) 
        throws IOException, ServletException;

您需要为每个国家/地区实现CountryFilter,让它成为名称与CC_Filter 模式匹配的Spring bean,其中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!
    

希望这可以帮助您解决问题。我相信这是一种非常灵活的方法,它甚至还有一个备用案例。要添加一个新国家/地区,您只需实现一个新的CountryFilter

【讨论】:

一个简单的问题。关于获取“过滤器”对象的这一行 boolean countinueChain = filter.doFilterForCountry(request, response);我要跟吗? CountryFilter filter=(CountryFilter) Class.forName(key).newInstance(); @MadanMadan Ups,我错过了一行。我现在正在编辑我的答案。感谢您指出这个错误。您必须从地图中获取过滤器。 非常感谢。现在还有一个问题。我们不需要用键和值填充过滤器映射吗?追随者如何获得一个没有该键值的类? CountryFilter filter = this.filters.get(key); @Madan 不,您不必填充该过滤器映射。 Spring 使用 @Autowired 注释为您执行此操作。只需扫描所有过滤器所在的包即可。 再次非常感谢!我忘了保留组件。呵呵..现在解决了!

以上是关于java Servlet过滤器基于位置的设置的主要内容,如果未能解决你的问题,请参考以下文章

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器过滤器等Web组件以及MVC架构

JAVA过滤器可以改变请求的内容或者重新设置请求 这里的请求就是这个servlet 或者jsp或

在 servlet 重定向之前使用过滤器修改响应 URL (Java/Tomcat)

拦截器和过滤器的区别

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

java跨域请求的方式