在Java Servlet应用程序中为HTTP 201响应设置Location标头的正确方法是什么

les*_*es2 35 java servlets http httpresponse http-headers

请考虑以下代码向客户端发送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);
Run Code Online (Sandbox Code Playgroud)

它通知客户端创建了一个新的"东西",并且可以在URL上找到它/app/things?id=42.问题是这个URL是相对的.这对于JSP来说是完美的,可以写成如下:

<img src="<c:url value="/things?id=42" />" />
Run Code Online (Sandbox Code Playgroud)

哪个会产生以下HTML:

<img src="/app/things?id=42" />
Run Code Online (Sandbox Code Playgroud)

这是我们想要的网络应用程序.

但我不相信这是我们想要的201响应位置标题.HTTP规范声明:

14.30位置

Location response-header字段用于将收件人重定向到Request-URI以外的位置,以完成请求或标识新资源.对于201(已创建)响应,Location是请求创建的新资源的位置.对于3xx响应,位置应该应该指示服务器自动重定向到资源的首选URI.字段值由单个绝对URI组成.

       Location = "Location" ":" absoluteURI
Run Code Online (Sandbox Code Playgroud)

一个例子是:

       Location: http://www.w3.org/pub/WWW/People.html
Run Code Online (Sandbox Code Playgroud)

我的问题是如何以适当的方式将servlet的相对URL转换为Location头的绝对URL.

我不相信使用:

request.getServerName() + ":" + request.getServerPort() + url;
Run Code Online (Sandbox Code Playgroud)

是正确的解决方案.应该有一个生成正确输出的标准方法(以便可以应用URL重写等).我不想创建一个hack.

Jul*_*hke 22

只需发送绝对路径.对绝对URI的限制是RFC 2616中的已知缺陷,将在HTTPbis中修复(请参阅http://trac.tools.ietf.org/wg/httpbis/trac/ticket/185).

请注意,RFC 7231 现在包含规范中的相对URI .有关如何处理相对URI的信息,请参阅其他答案.

  • 请注意,RFC 7231现在在规范中包含相对URI,请参阅[此处](https://tools.ietf.org/html/rfc7231#section-7.1.2):*"字段值由单个URI引用组成当它具有相对引用的形式时([RFC3986],第4.2节),最终值是通过根据有效请求URI([RFC3986],第5节)解决它来计算的."* (3认同)

Bal*_*usC 5

不幸的是,servlet API 没有提供直接返回上下文根之前的绝对 URL 的方法。为此,我多次不得不使用getRequestURL(),getRequestURI()和的组合getContextPath()

String absoluteContextRootURL = request.getRequestURL().toString().replace(request.getRequestURI().substring(1), request.getContextPath());
Run Code Online (Sandbox Code Playgroud)