【发布时间】:2018-01-24 10:27:26
【问题描述】:
servlet 是否支持如下 url:
/xyz/{value}/test
其中值可以替换为文本或数字。
如何在 web.xml 中映射它?
【问题讨论】:
-
相关:stackoverflow.com/questions/8252442/…(可能重复)。
标签: servlets get web.xml path-parameter
servlet 是否支持如下 url:
/xyz/{value}/test
其中值可以替换为文本或数字。
如何在 web.xml 中映射它?
【问题讨论】:
标签: servlets get web.xml path-parameter
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 filter 或homegrow your own URL rewrite filter。
【讨论】:
没有 Servlet 不支持这样的模式,其他人提到的可能方法是在xyz 之后使用/*,但这不会检查{value} 或/test。最好选择 Spring 或 JAX-RS。但是,如果您打算坚持使用 Servlet,则可以使用更好的方式来编写它:
@WebServlet(urlPatterns = {"/xyz/*"})
【讨论】:
正如其他人所指出的,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) { ... }
}
【讨论】:
您不应该在 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
}
}
【讨论】:
如上所述,基本 servlet 不支持您在问题中指定的模式。 Spring MVC 确实支持模式。 Here 是指向Spring Reference Document 中相关部分的链接。
【讨论】:
它确实支持映射该 url;但不提供任何验证。
在你的 web xml 中,你可以这样做......
/xyz/*
但这并不能保证结尾的test 存在并且它是最后一项。如果你正在寻找更复杂的东西,你应该试试 urlrewritefilter。
【讨论】: