39

servlet 是否支持如下 url:

/xyz/{value}/test

其中值可以替换为文本或数字。

如何在 web.xml 中映射它?

4

6 回答 6

52

Servlet API 不支持*在映射中间使用 URL 模式通配符。它只允许通配符*出现在映射的末尾/prefix/*或映射的开头*.suffix

使用标准允许的 URL 模式语法,最好的办法是将其映射/xyz/*并使用HttpServletRequest#getPathInfo().

因此,给定一个<url-pattern>/xyz/*</url-pattern>,这是一个基本的启动示例,如何提取路径信息、空检查和数组索引越界检查省略:

String pathInfo = request.getPathInfo(); // /{value}/test
String[] pathParts = pathInfo.split("/");
String part1 = pathParts[1]; // {value}
String part2 = pathParts[2]; // test
// ...

如果您希望使用 Apache HTTPD 进行更细粒度的控制mod_rewrite,那么您可以查看Tuckey 的 URL 重写过滤器自制您自己的 URL 重写过滤器

于 2012-01-03T16:46:18.727 回答
9

正如其他人所指出的,servlet 规范不允许这样的模式。但是,如果适合您的用例,您可能会考虑确实允许此类模式的 JAX-RS 。

@Path("/xyz/{value}/test")
public class User { 

    public String doSomething(@PathParam("value") final String value) { ... }

}

或者:

@Path("/xyz/{value}")
public class User { 

    @Path("test")
    public String doTest(@PathParam("value") final String value) { ... }

}

(相关:https ://stackoverflow.com/a/8303767/843093 。)

于 2012-01-03T19:53:23.603 回答
3

它确实支持映射该 url;但不提供任何验证。

在您的 web xml 中,您可以执行此操作....

/xyz/*

但这并不能保证尾随test存在并且它是最后一项。如果您正在寻找更复杂的东西,您应该尝试 urlrewritefilter。

http://code.google.com/p/urlrewritefilter/

于 2012-01-03T16:46:27.287 回答
1

您不应该在 web.xml 中这样做,而是可以将每个请求指向您的过滤器(Patternfilter)并检查 URL

package com.inventwheel.filter;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

/**
 * Servlet Filter implementation class PatternFilter
 */
@WebFilter("/*")
public class PatternFilter implements Filter {

    /**
     * Default constructor. 
     */
    public PatternFilter() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        // TODO Auto-generated method stub
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            String servletPath = ((HttpServletRequest)request).getServletPath();
            String requestURI = ((HttpServletRequest)request).getRequestURI();
            Pattern pattern = Pattern.compile(".*"+servletPath+"/(.*)");
            Matcher matcher = pattern.matcher(requestURI);
            if (matcher.matches())
            {
            String param = matcher.group(1);
            // do stuff with param here..
            }

        chain.doFilter(request, response);
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

}
于 2012-01-03T17:55:43.433 回答
0

如上所述,基本 servlet 不支持您在问题中指定的模式。Spring MVC 确实支持模式。 Spring 参考文档中相关部分的链接。

于 2012-01-03T16:58:35.470 回答
0

没有 Servlet 不支持这样的模式,其他人提到的可能方法也是使用/*afterxyz但不检查{value}or /test。最好选择 Spring 或 JAX-RS。但是,如果您打算坚持使用 Servlet,则可以使用一种更好的方式来编写它:

@WebServlet(urlPatterns = {"/xyz/*"})

于 2020-08-25T20:20:08.527 回答