【问题标题】:Servlet and path parameters like /xyz/{value}/test, how to map in web.xml?Servlet 和 /xyz/{value}/test 等路径参数,如何映射到 web.xml 中?
【发布时间】:2018-01-24 10:27:26
【问题描述】:

servlet 是否支持如下 url:

/xyz/{value}/test

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

如何在 web.xml 中映射它?

【问题讨论】:

标签: servlets get web.xml path-parameter


【解决方案1】:

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's URL rewrite filterhomegrow your own URL rewrite filter

【讨论】:

  • 这真的是 方式 需要提取不是 GET 参数的 url 参数吗?这似乎相当臃肿,难以维护,容易出现偏移错误和一般的 1995 年。
  • @Herbert:只需在 Servlet API 之上使用支持路径参数的框架,例如 JAX-RS 或 MVC。
  • 另一个选项是 getRequestURI(),在我的例子中 getPathInfo() 是空的。
  • @leventunver:它在过滤器中将是空的,或者当请求中的某处使用了执行不良的请求包装器时,或者由于 servlet 容器中的错误。
  • 我修改了一个扩展 GenericFilterBean 的类。使用 ServletRequest 作为输入。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    正如其他人所指出的,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.)

    【讨论】:

      【解决方案4】:

      您不应该在 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
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        如上所述,基本 servlet 不支持您在问题中指定的模式。 Spring MVC 确实支持模式。 Here 是指向Spring Reference Document 中相关部分的链接。

        【讨论】:

          【解决方案6】:

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

          在你的 web xml 中,你可以这样做......

          /xyz/*
          

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-03-01
            • 2016-07-05
            • 2013-01-20
            • 2017-11-05
            • 1970-01-01
            • 2012-04-17
            相关资源
            最近更新 更多