UPDATE
A few additional digging showed that the thrown exceptions were removed, and the actual problem is that the thrown UriInfocannot be resolved in the AsyncResponse stream!
Access to @Context UriInfo uriInfo;during AsyncResponse.resume()gives the following message LoggableFailure:
Unable to find context data like: javax.ws.rs.core.UriInfo
ORIGINAL
According to RFC 7231 HTTP / 1.1 Semantics and Control , a POSTmust return 201 CREATEDand provide a new resource location in the header:
the source server SHOULD send a 201 (Created) response containing a location header field that provides an identifier for the primary resource created (Section 7.1.2) and a view that describes the status of the request, referencing the new resource (s).
When writing a synchronous server, REST javax.ws.rs.core.Responseoffers an abbreviation Response.created()that does just that.
I would save a new object, build URIand return
return Response.created(createURL(created)).build();
However, when I switch to an asynchronous approach, using
@Suspended javax.ws.rs.container.AsyncResponse
The HTTP request on the client will hang indefinitely:
@POST
public void createUser(@Valid User user, @Suspended AsyncResponse asyncResponse) {
executorService.submit(() -> {
User created = userService.create(user);
asyncResponse.resume(
Response.created(createURL(created)).build()
);
});
}
Through a trial error, I found that the changed location header is responding. If I return my object and install 201 CREATEDwithout touching the header, the request will eventually resolve:
@POST
public void createUser(@Valid User user, @Suspended AsyncResponse asyncResponse) {
executorService.submit(() -> {
User created = userService.create(user);
asyncResponse.resume(
Response.status(Status.CREATED).entity(created).build() //this works
//Response.created(createURL(created)).build()
);
});
}
So what's the problem? I do not understand the concept?
RestEasy GlassFish4.1
, !
- , .