The only solutions I can think of invloves "Cloning the InputStream" (another link). Seems like double the work, but I don't see how else it can be achieved (without having to write a bunch of MessageBodyReaders).
Then we can just use ContainerRequestContext.setProperty(String, Object)
to set an arbitrary property than can be obtained throughout the request/response filter chain. In the response filter, you can use ContainerResponseContext.getProperty(String)
.
Here's an example, where I am expecting JSON, and using Jackson ObjectMapper to get a JSON Map and getting the id
value, then setting the property in the context.
@Provider
public class RequestFilter implements ContainerRequestFilter {
ObjectMapper mapper = new ObjectMapper();
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
if (!requestContext.getMethod().equalsIgnoreCase("POST")) {
return;
}
InputStream entityStream = requestContext.getEntityStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = entityStream.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
String contentType = requestContext.getHeaderString(HttpHeaders.CONTENT_TYPE);
if (MediaType.APPLICATION_JSON.equals(contentType)) {
// User Jackson ObjectMapper to get JSON as Map
Map<String, Object> jsonMap = mapper.readValue(
new ByteArrayInputStream(baos.toByteArray()),
TypeFactory.defaultInstance().constructMapType(
Map.class, String.class, Object.class));
Object id = jsonMap.get("id");
// Put id into context as property to be retrieved from response filter
requestContext.setProperty("id", id);
}
requestContext.setEntityStream(new ByteArrayInputStream(baos.toByteArray()));
}
}
The above example uses Jersey 2.x. If you are using Jersey 1.x, I don't see any method in the ContainerRequest
to set any arbitrary property, but I guess you could just set a temporary header
containerRequest.getRequestHeaders().putSingle("X-Temp-ID", id);
Then you can just get the header in the response filter.