Jersey/JAX-RS WriterInterceptor and HTTP Status - jersey

I have a problem with Jersey, I am writing a WriterInterceptor which should save the answer to the database, the problem is that I cannot retrieve the httpstatus, to avoid saving the answer in case of an error, I tried #Context HttpServletResponse but the status is 200 when it becomes 500 shortly after, how can I inject 'Response'? Or ContainerResponse/ContainerResponseContext?

Related

ResponseBodyEmitter with mutliple HTTP code status

For some security reason, we have added a common spring filter that perform a cross-cutting check and drop a 403 when a security rule is broken.
The solution is working fine in case of synchronous endpoint (i.e. returning a ResponseBody<SomeDTO>)
However, we have several asynchronous endpoints which return ResponseBodyEmitter.
If (checks == false){
// Then the filter should erase the response body and override the http status to 403.
}
For asynchronous method,the checks are performed during the response sending.
Hence the endpoint may send at the beginning 200 with a response body and then drops the connection with 403 and empty body.
Question:
From design wise, is this behavior coherent with REST ? (i.e. OK OK OK and then FORBIDDEN)
A HTTP request can only return 1 HTTP response, so "OK OK OK and then FORBIDDEN" is not actually possible. So REST doesn't care if you have some internal state that defaults to 200, eventually becomes 403 and then the last one gets sent back to the client. HTTP and REST doesn't know what goes on in your server leading to that 403.
However, if you have some mechanism that does permission checks after processing the entire request, and if the user doesn't have permission it erases the response body and sets a 403 response, that only seems reasonable for safe methods (e.g.: read-only methods like GET).

How do I get rid of okhttp3 "A connection to ... was was leaked" warning when returning a minio stream as spring ResponseEntity?

I am reading a file with minio and have a REST controller that returns the inputstream given by minio as an InputStreamResource. Here is my code:
#GetMapping("/download")
fun download(): ResponseEntity<InputStreamResource> {
// read file from minio
// getObjectResponse is an InputStream
...
val getObjectResponse = minioClient.getObject(getObjectArgs)
return ResponseEntity.ok().body(InputStreamResource(getObjectResponse))
}
According to this question wrapping an InputStream into a InputStreamResource is correct, and spring is supposed to close the underlying InputStream after the reponse is delivered. Yet I still get the infamous
okhttp3.OkHttpClient: A connection to ... was leaked. Did you forget to close a response body?
What are my options here? I would rather not need to copy and buffer the minio content into memory as these files tend to be very large.
As long as you close any of Response, ResponseBody or a stream like ResponseBody.inputStream() then the OkHttp response will be cleaned up.
You are reliant on the caller who accepts your InputStreamResource to close it correctly.
I'd suggest wrapping/decorating the input stream you pass into InputStreamResource and logging when and where call is closed.
By using Yuri Schimkes suggestion to improve logging and some debugging I found out that spring is closing the inputstream only when a HTTP 200 is returned and the inpustream is actually read and delivered. In my case sometimes caching happened (spring magic with etags) and spring returned a HTTP 304 without consuming and closing the inputstream.

Difference between HttpStatus.OK and HttpStatus.ACCEPTED

I am about to implement a REST api. I want to know what's the difference between HttpStatus.OK and HttpStatus.ACCEPTED:
return new ResponseEntity<User>(u, HttpStatus.OK));
And
return new ResponseEntity<User>(u, HttpStatus.ACCEPTED);
As per Spring documentation given on this link
HttpStatus.OK
200 Ok means The request has succeeded. The information returned with the response is dependent on the method used in the request
HttpStatus.ACCEPTED:
202 Accepted. means The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
for More information on HTTP response Status Code Definitions please visit this link

Servletrequest returns null sessions

I am getting a strange error where the session I get from the request is sometimes null. Code looks like this:
#Stateless
#Path("/login")
public class GetLogin {
#Context
private HttpServletRequest httpRequest;
#POST
#Produces(MediaType.APPLICATION_JSON)
public Response login(){
final HttpSession session = httpRequest.getSession(true);
sessionId = session.getId();//Sometimes gives nullpointer Exceptions
.....//Rest works fine if that step holds
When I call to get the session id I sometimes get a nullpointer exception. Why is that? Is there anything I can do to stop that? I can repeat the exact same call over and over and it randomly creates nullpointer exceptions due to that while other times it works just fine. I have tried doing this all sort of ways, with methods waiting for it to get ready and so on. What I learned was that if it don't get ready instantly it will never get ready.
The get cookies method on the request do occasionally fail as well bit that is easy to work around by just taking the cookies as arguments in the function. Also it seems like I can get around this by telling the frontend to repeat the call if the first one failed, the second call always succeeds then for some reason. But that feels like a dirty solution, so I really want to fix this...
Any ideas?
Edit: Apparently if I let it fail it fails every other time, but if I handle it so that the servlet don't crash it fails 4 times in a row and then succeeds once. I tried doing this on a fresh install, I took the standard netbeans example rest webapp and just added the HttpRequest to it and then printed out the session id. If anyone got this to work please show me how...

Openrasta Data Serialization Issue

I am currently using openRasta to build Rest Api.I am observing strange behavior while sending Ajax requests.Sometimes request is successful sometime it fails and it gives following exception.
{Exception:
System.Runtime.Serialization.SerializationException: Expecting element 'root' from namespace ''.. Encountered 'None' with name '', namespace ''.
at System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName)
at System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader)
at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(Stream stream)
at OpenRasta.Codecs.JsonDataContractCodec.ReadFrom(IHttpEntity request, IType destinationType, String paramName)
at OpenRasta.OperationModel.Hydrators.RequestEntityReaderHydrator.TryReadPayloadAsObject(IHttpEntity requestEntity, IMediaTypeReader reader, IOperation operation)}
One thing i have observed is that when i keep browser idle for some time say more than 10 minutes i can see the request in firebug but it shows status as pending for long time and when it hits server it gives above exception.But same works fine sometimes.
Can anybody explain me this behavior?If want i can provide some additional code related to it.
The delay may just be caused by asp.net having to restart when you finally get out of idle, which takes a little while.
As for the error, it seems to be that the json data contract serializer can't parse the request. I'd advise to check a couple of things, and if it fails post here the details so we can help you further.
That the body is indeed correct at the time the error is triggererd (with fiddler)
That you do not have some asp.net-specific issues that would prevent the request from arriving correctly to the asp.net pipeline, such as cookies-based authentication or session management
That the request is not intercepted by any http module (anti forgery tokens etc).
Please provide your mappings, entities and a copy of the OR log (which you can get by attaching a debugger to the server process) and we'll try and help you further.

Resources