Need to Set HTTP Headers Conditionally on Servlet Response - java

I want to set HTTP headers depending on the type of response. My problem is that some reponses commit their headers before I can set mine. Any suggestions about how to handle this?

One idea is to set the response header in the response object in a filter before the servlet is called.
Another one is to provide the servlet with a response wrapper that prevents the real response from actually being committed. This might entail buffering the response body in memory.
But I think that the best approach is to modify the servlets so that they set the required headers.
Do I HAVE to buffer the entire response by providing my own outputstream to the wrapper ? Can I overwrite flush() or something like that ?
It is up to you how you implement it. The constraint is that response wrapper object must somehow arrange that the special header gets added before the writing of the response body starts. The conceptually simple way is to buffer the response body, but you could also get the response wrapper to provide an output stream / writer that adds the header before the first flush to the real response output stream / writer.
I am worried about buffering causing performance issues
Yes, well it could do, though you would need to look at the entire webapp to determine if this is significant.
From a performance perspective, the best solution is to get the servlet to set the header itself.

Related

Determining the HTTP method for payload transfer from client to server

I have a use case where some context needs to be transferred from the UI to the backend and backend needs to decide and send the response based on that context.
This can be achieved by sending the context through request body and at the server side, by parsing the request body, the representation can be sent in the response body.
My doubt is which http method is suitable for this?
GET: If we use GET, we can send the request body but it is advised that the body should not have any semantics related to the request.
See this: http-get-with-request-body
So I am left with POST or PUT but these corresponds to updating or creating a resource and using them might be little misleading.
So my question is what is the appropriate HTTP method that could be used in this scenario which is acceptable in the RESTful design standpoint.
Appreciate the response.
I am thinking to use POST or PUT as there are no restrictions on consuming the request body on the server side.
EDIT:
I think POST would serve my purpose.
The rfc HTTP RFC 7231 says that POST can be used for:
Providing a block of data, such as the fields entered into an HTML form, to a data-handling process
So the data handling process for me is the backend server and HTML Form is equivalent to any UI element.
So I can make use POST method to send the data to backend and send the existing resource representation as response body with http-status code being 200
Please bear in mind that GET must be used for data retrieval only, without side effects. That is, GET is both safe and idempotent (see more details here).
If the operation is meant to be idempotent, go for PUT:
4.3.4. PUT
The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload. A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being sent in a 200 (OK) response. [...]
Otherwise, go for POST, which is a catch all verb:
4.3.3. POST
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics. [...]
I would go for POST because in REST, PUT is used to create a new resource like user.
There is a PATCH post method, that is for changing things maybe thats what you are looking for
So my question is what is the appropriate HTTP method that could be used in this scenario which is acceptable in the RESTful design standpoint.
The world wide web is about as RESTful an example as you are going to find, and HTML forms only support GET (which should not have a request body) and POST. So POST must be fine (and it is).
More generally, POST can be used for anything; the other methods should be used when they are a better semantic fit. For example, you can use POST to make a resource unavailable, but DELETE is more explicit, and generic components can do sensible things because they recognize the semantics. PUT is a better choice than POST when what you are intending is to provide the server with a new representation of a resource, and so on.
I am not able to understand why the payload of the HTTP GET is forbidden
Payload of the HTTP GET is forbidden because the standard says "don't do that".
I believe it is written that way to simplify the rules for caching the response. As written, cache implementations only have to worry about header data (including information on the start-line).
But it could be as simple as the fact that the older versions of the standard didn't require that generic components do anything specific with the message-body of a GET request, and therefore modern specifications say "don't do that" in order to maintain backward compatibility. (One of the important constraints in designing long-lived systems is that you don't break older implementations.)

Java #Pathparam with POST Method

I have to make request with only one parameter for example:
example.com/confirm/{unique-id-value}
I don't expect to get any data in body, only interested in Response Code.
Need advice which method to use GET or POST
GET i think is also OK because, making request with pathparam, but on the other hand POST is also right to use, because i don't expect to receive any data from body, just making informative request and interested in only status code of request result.
The confirm suggests that a request to this URL will change some state on a server by 'confirming' some 'task' that is identified by a unique ID. So we talk about the Reource (the R in REST) of a 'task confirmation'. A GET request will get the current state of such a Resource. GET must not have side effects like changing the state of the 'task confirmation' resource. If it is unconfirmed before a GET request, it must be unconfirmed after such a request.
If you want to change the state of the 'task confirmation' Resource, you must use a different HTTP verb. But since you write that you will not pass any request body, it is hard to recommend a RESTful approach.
One disadvantage of using GET is that its response is often cached, so if you inquire about the same ID repeatedly, you might not get the results you expect, unless you do some shenanigans to prevent caching (such as appending a unique timestamp to the GET URL for every request). POST requests, on the other hand, are never cached, so you would get the correct result every time without any additional work.

Setting Request Header in java

Is there any way to modify or set-header of request inside action class? I want to modify it or you can say i want to put flag inside request Header just like we put values in 'attribute' and parameters.
You can do this using HttpServletRequestWrapper. But it's quite dirty solution. Are there really no other ways to solve your problem?
You cannot. Request parameters returned from the servlet are unmodifiable Map. You cannot add/delete content returned from request (via servlet).
In order to set a flag, my suggestion is to store it in a session, and on another action, retrieve the flag & delete it from session.
I think you'd need to wrap the original request into a request class containing the change you wish to have.
It might be better design to have the request parameters parsed earlier in processing to such objects that make more sense to your application logic, and then set the state of those objects in the place where you now would like to modify the original header.
The answer to this depends on what problem you're trying to solve.
One of your comments suggests you're trying to test; if this is the case you have two basic options:
Use a mock request (unit-style testing).
Change the header from the client (integration-style testing).
For testing from real clients, set headers on the client side.
For mocking client interactions, you should be using some form of mock. StrutsTestCase, for example, provides MockStrutsTestCase (outside container) and CactusStrutsTestCase (inside container) classes allowing easy manipulation of request properties and characteristics.
If you are trying to open a URL connection using Java,
you can something like this What is the proper way of setting headers in a URLConnection?
If you can make requests with a browser,
You can use this Firefox plugin to add/modify any number of request headers.
https://addons.mozilla.org/en-US/firefox/addon/modify-headers/
Good Luck
You need to give more details. It sounds like you want to manipulate the request header once the server has received the request. I'm not sure I understand why you would want to do that. Modifying the response headers make sense. But not the request.
I think they only clean way you can do this is via an HttpServletRequestWrapper
Just override getHeader, getHeaders, getHeaderNames and you are good to go.

Writers and OutputStreams in Java EE applications and filters

I've recently encountered the following exception...
java.lang.IllegalStateException: Cannot obtain Writer because OutputStream is already in use
I understand the nature of the exception; namely the code can use a Writer or OutputStream but never both in the same request. How is code further down the stack supposed to handle the case where one already exists? OR is there a design/arch pattern that can avoid this problem in the first place?
Example; consider a 3rd party filter that decorates the output of a request and it gets an OutputStream. How is a filter or a servlet that needs to work with a Writer supposed to "know" that an OutputStream was already opened and should it care? The converse is also a valid Q.
I'll attempt to address the more specific question raised in your example:
consider a 3rd party filter that decorates the output of a request and it gets an OutputStream. How is a filter or a servlet that needs to work with a Writer supposed to "know" that an OutputStream was already opened and should it care?
The Servlet API also disallows the use of both Writer and OutputStream when populating the response, as indicated in the API documentation for the ServletResponse.getWriter() method:
Either this method or getOutputStream() may be called to write the body, not both.
If a filter (third party or otherwise) wants to write to the response, especially after servlet(s) have generated it, it ought to assume that
the servlet has used either the Writer or the OutputStream to populate the response.
the servlet would have invoked the close() method on the Writer or the OutputStream object.
To account for this, the filter must create a HttpServletResponseWrapper instance, pass it downstream to the servlet for population, read it back in again, and then populate the actual container-managed HttpServletResponse object.
The above would also hold good if the filter were to populate the response first (before the request is processed further). It should perform the population on the actual HttpServletResponse object, pass a wrapper downstream, and then write the contents of the wrapper to the actual object.
The design approach is surprisingly easy:
Do not use Java code (scriptlets) in JSP. This implicitly triggers getWriter().
Do not write anything to the response in a Servlet when you're going to forward to a JSP.
In other words, if you adhere the MVC ideology, there's basically nothing to worry about.
Another approach is to design the Filter so that it uses the Writer or OutputStream depending on a configuration setting in the web.xml. Then configure the Filter according to Servlet that it is filtering requests for.

Avoiding IllegalStateException in Java/Servlet web stack

I don't know, but I feel that IllegalStateException is causing undo headache. If I have a request say a JSP or some other servlet and need to associate a filter with that request. I can't do any other modifications to the output to the client if the response has already been committed?
For example, I see in JSP code that sets the mimetype to response.setContent("html") and then I have a filter associated with the JSP that needs to set the mimetype to something
else. setContent("image") or "xhtml". But I get an IllegalStateException?
Is there a way to clear the previous response that has been committed or is there something to avoid this issue.
This is on websphere.
I think you need to rethink how you're preparing and returning your responses. You can't write to the response (which may write to the client) and then change your mind.
Leaving aside the question of why your solution has to change the return type, I would write to some dummy container object with the return date + type, and make this mutable. Only once your servlet has completed all its work would you then write this object (type+content) to the outputstream.
(to clarify, I don't think servlet filters are the right approach for this. They will intercept the request, and the response, but the response population is the responsibility of the servlet)
I agree with the other posters that this is ugly but you can create an HttpServletResponseWrapper in your filter that would hijack the output and pass that wrapper to the chain instead of the original response object.
Your premise to execute a jsp outputting HTML and then have a filter changing the content type to something else like image all in the same response makes no sense. A response can only return a single artefact be it a HTML file or image. There is no way to return both within the same response- any attempt to do so is nonsense . It makes no sense to send some HTML with image binary tacked on the end. The content type is for the entire response. You cannot package multiple thingos in the one response.
Sometimes you can resetBuffer() if the output as not exceeded the buffersize. The best approach is to avoid this facility and deyermi e what to do before you start outputting a response..

Categories