我认为不可能使用
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!
}
}
希望这能帮助你解决问题。我认为这是一种非常灵活的方法,甚至有一个后备方案。要添加一个新国家,您需要做的就是实施一个新的
国家过滤器
.