【问题标题】:How to define subpaths in tomcat 6 web.xml servlet-mapping servlet-pattern如何在 tomcat 6 web.xml servlet-mapping servlet-pattern 中定义子路径
【发布时间】:2014-05-24 05:24:53
【问题描述】:

我的目标是使用以下模式的所有 url 到达相同的 servlet servlet1:

myserver.com/path1/*

其中 * 可以是“x”、“x/xx”、“x/xx/x.cfg”等任何内容。
最后,我只想处理正则表达式 [0-9a-zA-Z]+.(cfg|xml|htm) 之后的 url,但我可以在 servlet 中这样做。 servlet 解析原始 URL 并动态构建请求的配置文件。

当我有以下映射时

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

正如预期的那样,网址 myserver.com/path1 指向 servlet1。
当我使用以下看起来对我有意义的映射时:

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

我仍然可以通过 url myserver.com/path1/ 访问 servlet 1。
我无法通过 url myserver.com/path1/path2 访问 servlet i>,这个网址实际上让我回到了欢迎文件条目。

实际上,无论我输入什么模式,任何带有第二条路径的东西都会让我回到欢迎文件条目。对于第二条路径,我的意思是 myserver.com/path1/*,其中 * 超过 0 个字符。

我目前看到的唯一选择是让 Welcome-files 条目处理我的请求(丑陋)或使用

.cfg .xml *.htm

这使得像 myserver.com/XXX.cfg 这样的 URL 可以工作(myserver.com/X/XXX.cfg 不起作用)。这也很丑陋,并且会干扰该 web 应用程序的未来开发。

如何让映射按我想要的方式工作?

【问题讨论】:

  • 您的配置文件中似乎有一个错误,因为/path1/* 应该像魅力一样工作
  • 在这里阅读URL patterns
  • Andremoniy:知道我可以去哪里看吗?除了欢迎文件之外,该应用程序的 web.xml 只有几个正常工作的 条目。

标签: java tomcat servlets tomcat6 url-pattern


【解决方案1】:

如果这条路径 /path1 大部分时间都被调用,请尝试使用 Filter 并将您的逻辑放在那里。

您可以完全控制此过滤器。您可以在 web.xml 中定义以逗号分隔的跳过 URL。

我将此过滤器用于压缩逻辑。

web.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>

MyFilter.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() {

    }
}

【讨论】:

  • 如果我调用 filterChain.doFilter(request, response); 是否会像过滤器不存在一样工作? ?我了解如何直接写入来自过滤器类/方法的请求,但如何返回我的 servlet?还是应该将 servlet 逻辑放在过滤器中?
  • 过滤器就像一个 servlet 一样工作。如果您不想处理此请求,请使用filterChain.doFilter(request, response); 表示您想跳过与此过滤器无关的此 URL。
  • 是的,您可以将您的 servlet 逻辑放入此过滤器中。我建议您将逻辑放在一个单独的文件中,就像一个服务一样。
  • 一切都会从这个过滤器中删除,因为它的url-pattern 被定义为/* 表示每个请求。您也可以在过滤器中检查 cfg|xml|htm 模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 2012-08-22
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
相关资源
最近更新 更多