请考虑以下代码向客户端发送HTTP 201“创建”响应:
String url = "/app/things?id=42"; // example
response.setStatus(HttpServletResponse.SC_CREATED);
response.setContentType("text/plain");
response.setHeader("Location", url);
response.getWriter().print(url);
它通知客户端已创建新的"thing",并且可以在URL /app/things?id=42
找到它 . 问题是这个URL是相对的 . 这对于JSP来说是完美的,可以写成如下:
<img src="<c:url value="/things?id=42" />" />
哪个会产生以下HTML:
<img src="/app/things?id=42" />
这是我们想要的网络应用程序 .
但我不相信这是我们想要的201响应位置 Headers . HTTP规范states:
14.30位置Location response-header字段用于将收件人重定向到Request-URI以外的位置,以完成请求或标识新资源 . 对于201(已创建)响应,Location是请求创建的新资源的位置 . 对于3xx响应,位置应该应该指示服务器自动重定向到资源的首选URI . 字段值由单个绝对URI组成 . Location =“Location”“:”absoluteURI
一个例子是:位置:http://www.w3.org/pub/WWW/People.html
我的问题是如何以适当的方式将servlet的相对URL转换为Location头的绝对URL .
我不相信使用:
request.getServerName() + ":" + request.getServerPort() + url;
是正确的解决方案 . 应该有一个生成正确输出的标准方法(以便可以应用URL重写等) . 我不想创建一个hack .
5 回答
如果您使用的是JAX RS,
javax.ws.rs.core.Response
中有一个方法automatically converts relative URLs:但请注意,JAX RS实现CXF中存在一个错误leads to incorrect absolute URLs .
你可以试试
对于任何
..
或其他奇怪的规范化,至少应该是明智的 . 除此之外,我不比字符串操作好得多 .只需发送绝对路径 . 对绝对URI的限制是RFC 2616中的已知缺陷,将在HTTPbis中修复(请参阅http://trac.tools.ietf.org/wg/httpbis/trac/ticket/185) .
请注意RFC 7231 now includes relative URIs in the spec. 请参阅有关如何处理相对URI的其他答案 .
决定采用Julian Reschke的建议并违反规范!至少我添加了以下评论:
我不想自己发送绝对URI的原因是因为我在负载均衡器和其他 生产环境 基础设施背后遇到了问题 . 虽然在开发模式下“http:// localhost:8080 / foo”趋于正常工作:))
现在接受朱利安的答案......
不幸的是,servlet API没有提供直接将绝对URL返回到上下文根的方法 . 为此我有几次不得不使用getRequestURL(),getRequestURI()和getContextPath()的组合 .