43992

How to match http request and response using Jersey ContainerRequestFilter and ContainerResponseFilt

I have a highly concurrent server and need to implement some special logging. I need an easy way to match the request to the response. The filter() in ContainerResponseFilter has both the request and response. How ever I can not access the http post content because the stream has already been read.

Is there some way I can add an ID in the ContainerRequestFilter filter() and somehow have it automatically returned when the ContainerResponseFilter filter() is called? I can not modify the true applications.

I have another program that will need to process the log file and be able to match the request to the response.

Any other suggestions?

Answer1:

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.

Recommend

  • Linux FreeBSD shared object problem
  • Design heuristics for writing Python classes that interact with `scipy.integrate.odeint`?
  • How can I access an element from a list/array in a windows batch code?
  • What to look for when setting UpdateBatchSize
  • Find all elements that have a certain data attribute (regardless of value)
  • Grails Resources Plugin — How to get generated urls?
  • 1-element Array to scalar in Julia
  • Python regex catastrophic backtracking
  • Hudson - different build targets for different triggers
  • Merge several columns into one with specific conditions in R
  • writing unicode to binary file in python
  • date.js Parse method overrides Javascript Parse method
  • Why was the Profile provider not built into Web Apps?
  • SOLR - Querying Facets, return N results per Facet
  • Regarding Static class in c# [duplicate]
  • HSQLDB Statement and Java NaN doubles
  • While loop won't end when I tell it in JavaScript
  • HABTM associations in Rails : collecting and counting the categories of a model's children
  • Should a web service response include empty values?
  • Making Google Visualization - Annotation Chart to work in GWT
  • Alamofire and Reachability.swift not working on xCode8-beta5
  • Looking for good analogy/examples for monitor verses semaphore
  • How to match http request and response using Jersey ContainerRequestFilter and ContainerResponseFilt
  • How do I open a C file with a relative path?
  • Use of this Javascript
  • Setting up SourceTree to merge unity3d scenes with UnityYAMLMerge
  • Linq Objects Group By & Sum
  • Email format validation in mvc3 view
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • How to add date and time under each post in guestbook in google app engine
  • Do create extension work in single-user mode in postgres?
  • R: gsub and capture
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • How do I rollback to a specific git commit
  • How to format a variable of double type
  • Comma separated Values
  • Buffer size for converting unsigned long to string
  • Why joiner is not used after Sequence generator or Update statergy
  • coudnt use logback because of log4j
  • How to load view controller without button in storyboard?