我们正在使用Dropwizard / Jersey来构建Web服务。资源具有路径,并且该方法具有子路径。当返回创建的响应(201)时,我们获得的方法的路径被添加到我们提供的位置之前。当一个位置(我知道设计)返回状态OK时,一切都很好,并且就像我们提供的那样返回位置。
我们如何返回不是我们方法位置的子路径的位置?
在下面的示例中: 获取“http:// localhost / foo / bar”(创建状态)以“http:// localhost / foo / bar / wibble”的位置响应(注意 / foo / bar )
当到达“http:// localhost / foo / baz”(ok状态)时,响应位置为“http:// localhost / wibble”,这就是我们想要的。
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import java.net.URI;
@Path("/foo")
public class FooResource {
@POST
@Path("/bar")
public Response bar() {
URI uriOfCreatedResource = URI.create("/wibble");
return Response.created(uriOfCreatedResource).build();
}
@POST
@Path("/baz")
public Response baz() {
URI uriOfCreatedResource = URI.create("/wibble");
return Response.ok().location(uriOfCreatedResource).build();
}
}
答案 0 :(得分:7)
如果有人偶然发现这件事;我挖了泽西的代码,看看为什么会这样。这应该解释你的问题&卡罗的解决方法。
com.sun.jersey.spi.container.ContainerResponse包含此gem:
private void setHeaders(MultivaluedMap<String, Object> headers) {
this.headers = headers;
Object location = headers.getFirst(HttpHeaders.LOCATION);
if (location != null) {
if (location instanceof URI) {
final URI locationUri = (URI)location;
if (!locationUri.isAbsolute()) {
final URI base = (statusType.getStatusCode() == Status.CREATED.getStatusCode())
? request.getAbsolutePath() // WHY!?
: request.getBaseUri();
location = UriBuilder.fromUri(base).
path(locationUri.getRawPath()).
replaceQuery(locationUri.getRawQuery()).
fragment(locationUri.getRawFragment()).
build();
}
headers.putSingle(HttpHeaders.LOCATION, location);
}
}
}
换句话说:出于某种原因,有人认为如果响应状态代码是201,则以不同方式处理位置标题是个好主意。像Carlo注意到的那样,使用绝对路径可以避免这个问题。
答案 1 :(得分:4)
在GlassFish(JavaEE6)上发生了我的事。 我认为这是一个错误,但我从未设法将代码挖掘到实际的URI转换....
我找到了一个解决方法:
public Response bar(@Context UriInfo info) {
URI absoluteURI=info.getBaseUriBuilder().path("/wibble").build();
return Response.created(absoluteURI).build();
}
答案 2 :(得分:0)
在Jersey 2.x中,相关代码被完全重写并移至另一个地方。在类org.glassfish.jersey.server.ServerRuntime
内,在编写响应数据时调用以下方法:
private static void ensureAbsolute(final URI location, final MultivaluedMap<String, Object> headers,
final ContainerRequest request) {
if (location == null || location.isAbsolute()) {
return;
}
// according to RFC2616 (HTTP/1.1), this field can contain one single URI
headers.putSingle(HttpHeaders.LOCATION, request.getBaseUri().resolve(location));
}
如前所述,除非应用程序为Location标头设置绝对URI(以http:
或ftp:
等模式开头的URI),否则Jersey会自动使用请求的基URI预先设置它。
很奇怪泽西岛不允许控制或禁用此行为。