2015-03-11 5 views
1

Мое приложение посещается из разных стран, и я использую общий сервлет Filter (MyFilter.java) для управления всеми запросами. Можно ли перенаправить на другие сервлеты на основе посетителя страны? В настоящее время моя конфигурация web.xml нижеjava Servlet Filter Настройки на основе местоположения

<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) 

Но я не знаю, как?

Я требую этого из-за различного поведения мы проводим на основе стран, например их мобильный без проверки, управление пользователей абонентское обслуживание и т.д.

Просьба представить мне предложения.

Спасибо,

+0

У вас есть страна в URL? Вы можете сопоставить фильтр в 'web.xml' по шаблону url. В противном случае вам нужно будет выполнить нужную логику внутри 'MyFilter'. –

+0

В URL-адресе я не могу иметь страну, но jsp может передать ее как параметр. Как сопоставить их в файле web.xml? –

+0

Вы не отображаете это в файле 'web.xml', но внутри вашего фильтра, с кодом. –

ответ

2

Я думаю, что для этого нельзя использовать web.xml. Тем не менее, вы можете выполнить то, что вам нужно, закодировав свой класс MyFilter, чтобы вам не нужно было его изменять при добавлении новой страны.

Я вижу, что вы используете Весну. Это хорошая новость, так как MyFilter на самом деле является фасолью, управляемой весной. Это означает, что к нему могут быть добавлены другие бобы. Мое предложение состоит в том, что у вас есть один компонент для каждой страны и один основной фильтр, на который будет поручено делегировать правильную страну.

Во-первых, пусть ваш 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 вызывается для каждого запроса.

Затем осуществить 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() { 
    } 
} 

Этот класс достаточно универсален. Вам не нужно менять его при добавлении или удалении страны. Хитрость заключается в том, чтобы использовать поведение Autowower Spring для коллекций. Если вы запустили autowire Map<String, T>, то Spring заполнит эту карту всеми экземплярами фасонов класса T, являющимися ключами, равными именам компонентов и значениями соответствующих экземпляров компонента.

Затем вам нужно интерфейс CountryFilter:

public interface CountryFilter { 

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

Вы должны были бы осуществить CountryFilter для каждой страны, позволяя ей быть Spring боб, чье имя соответствует шаблону 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! 
    } 
} 

Надеется, что это поможет вам решить вашу проблему. Я считаю, что это довольно гибкий подход, у него даже есть резервный случай. Чтобы добавить новую страну, все, что вам нужно сделать, это реализовать новый CountryFilter.

+1

Блестящий !!! Вы спасли мою жизнь. –

+1

Быстрый вопрос. Об этой строке, чтобы получить объект «фильтр» boolean countinueChain = filter.doFilterForCountry (запрос, ответ); Должен ли я делать следующее? Фильтр CountryFilter = (CountryFilter) Класс.forName (ключ) .newInstance(); –

+0

@MadanMadan Ups, я пропустил одну строчку там. Я редактирую свой ответ прямо сейчас. Спасибо, что указали на эту ошибку. Вы должны получить фильтр с карты. –

0

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

пожалуйста пройти через этот сайт !!

Используя этот сайт, я предлагаю вам добавить еще один фильтр, чтобы он проверял локаль & перенаправлять на нужный сервлет.

+1

Используя этот сайт, я предлагаю вам добавить еще один фильтр, чтобы он проверял локаль и перенаправлял нужный сервлет. –

Смежные вопросы