Как определить подпути в tomcat 6 web.xml servlet-mapping servlet-pattern

Моя цель — получить один и тот же сервлет servlet1 со всеми URL-адресами следующего шаблона:

myserver.com/path1/*

где * может быть что угодно вроде "x", "x/xx", "x/xx/x.cfg" и т. д.
В конце концов, я хочу обрабатывать только URL-адреса, следующие за регулярным выражением [0-9a-zA-Z ]+.(cfg|xml|htm), но я могу сделать это в сервлете. Сервлет анализирует исходный URL-адрес и динамически создает запрошенные файлы конфигурации.

Когда у меня есть следующее отображение

<servlet-name>servlet1</servlet-name>
<url-pattern>/path1</url-pattern>

как и ожидалось, URL-адрес myserver.com/path1 ведет к servlet1.
Когда я использую следующее сопоставление, похожее на то, которое имеет для меня смысл:

<servlet-name>servlet1</servlet-name>
<url-pattern>/path1/*</url-pattern>

Я все еще могу получить доступ к сервлету 1 с URL-адресом myserver.com/path1/.
Я не могу получить доступ к сервлету с URL-адресом myserver.com/path1/path2, этот URL фактически возвращает меня к записи приветственных файлов.

На самом деле все, что имеет второй путь, возвращает меня к записи приветственных файлов, независимо от того, какие шаблоны я ввожу. Под вторым путем я подразумеваю что-нибудь myserver.com/path1/*, где * длиннее 0 символов.

Единственные альтернативы, которые я вижу в настоящее время, — это позволить записи приветственных файлов обрабатывать мои запросы (уродливо) или использовать

.cfg.xml *.htm

что заставляет работать такие URL-адреса, как myserver.com/XXX.cfg (myserver.com/X/XXX.cfg не работает). Это тоже было бы некрасиво и помешало бы дальнейшей разработке этого веб-приложения.

Как мне заставить сопоставление работать так, как я хочу?


person ASA    schedule 10.04.2014    source источник
comment
Похоже на ошибку в вашем конфигурационном файле, потому что /path1/* должно работать как шарм   -  person Andremoniy    schedule 10.04.2014
comment
прочитайте здесь об URL узоры   -  person Braj    schedule 10.04.2014
comment
Andremoniy: Есть идеи, где я мог бы посмотреть? В файле web.xml этого приложения помимо приветственных файлов есть только несколько правильно работающих записей ‹servlet› и ‹servlet-mapping›.   -  person ASA    schedule 10.04.2014


Ответы (1)


Попробуйте использовать Filter, если этот путь /path1 вызывается чаще всего, и поместите туда свою логику.

У вас есть полный контроль над этим фильтром. Вы можете указать пропускаемые URL-адреса в файле web.xml, разделенные запятыми.

Я использовал этот фильтр для логики сжатия.

веб.xml:

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.x.y.z.servlet.MyFilter</filter-class>
    <init-param>
        <param-name>skipEqualsURIs</param-name>
        <param-value></param-value>
    </init-param>
    <init-param>
        <param-name>skipStartsWithURIs</param-name>
        <param-value></param-value>
    </init-param>   
    <init-param>
        <param-name>skipEndsWithURIs</param-name>
        <param-value></param-value>
    </init-param>   
</filter>

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Мой фильтр.java:

public class MyFilter implements Filter {

    /** The skip equals ur is set. */
    private Set<String> skipEqualsURIsSet = new HashSet<String>();

    /** The skip starts with ur is set. */
    private Set<String> skipStartsWithURIsSet = new HashSet<String>();

    /** The skip ends with ur is set. */
    private Set<String> skipEndsWithURIsSet = new HashSet<String>();


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        String skipEqualsURIs = filterConfig.getInitParameter("skipEqualsURIs");
        if (skipEqualsURIs != null && skipEqualsURIs.trim().length() > 0) {
            for (String skipURI : skipEqualsURIs.split(",")) {
                skipEqualsURIsSet.add(skipURI);
            }
        }

        String skipStartsWithURIs = filterConfig.getInitParameter("skipStartsWithURIs");
        if (skipStartsWithURIs != null && skipStartsWithURIs.trim().length() > 0) {
            for (String skipURI : skipStartsWithURIs.split(",")) {
                skipStartsWithURIsSet.add(skipURI);
            }
        }

        String skipEndsWithURIs = filterConfig.getInitParameter("skipEndsWithURIs");
        if (skipEndsWithURIs != null && skipEndsWithURIs.trim().length() > 0) {
            for (String skipURI : skipEndsWithURIs.split(",")) {
                skipEndsWithURIsSet.add(skipURI);
            }
        }
    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
            FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String uri = httpServletRequest.getRequestURI();

        if (isSkip(uri)) {
            // do what you want to do based on skip logic
            // filterChain.doFilter(servletRequest, servletResponse);
        } else {
            // do what you want to do based on skip logic
            // filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    private boolean isSkip(String uri) {
        boolean skip = skipEqualsURIsSet.contains(uri);

        if (!skip) {
            for (String skipURI : skipStartsWithURIsSet) {
                if (uri.startsWith(skipURI)) {
                    skip = true;
                    break;
                }
            }
        }

        if (!skip) {
            for (String skipURI : skipEndsWithURIsSet) {
                if (uri.endsWith(skipURI)) {
                    skip = true;
                    break;
                }
            }
        }

        return skip;
    }

    @Override
    public void destroy() {

    }
}
person Braj    schedule 10.04.2014
comment
Правильно ли, что он будет работать так, как если бы фильтра не было, если я вызову filterChain.doFilter(request, response); ? Я понимаю, как напрямую писать запрос из класса/методов фильтра, но как вернуть мой сервлет? Или я должен поместить логику сервлета в фильтр? - person ASA; 10.04.2014
comment
Фильтр работает так же, как сервлет. используйте filterChain.doFilter(request, response);, если вы не хотите обрабатывать этот запрос, означает, что вы хотите пропустить этот URL-адрес, который не имеет отношения к этому фильтру. - person Braj; 10.04.2014
comment
Да, вы можете поместить свою логику сервлета в этот фильтр. Я предлагаю вам поместить логику в отдельный файл, который похож на сервис. - person Braj; 10.04.2014
comment
Из этого фильтра уйдет все, потому что его url-pattern определяется как /* означает каждый запрос. Вы также можете проверить шаблоны cfg|xml|htm в фильтре. - person Braj; 10.04.2014