• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Rob Spoor
  • Bear Bibeault
Saloon Keepers:
  • Jesse Silverman
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Al Hobbs
  • salvin francis

Modifying HTTP response code and content in java web application

 
Greenhorn
Posts: 3
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My goal is to modify the http response status code and the content that comes with it (not using spring by the way).
The current response I'm getting is an HTTP 501 and I would like to modify that response to return an HTTP 200 instead with a custom message.

I've tried using and found out that that won't work (as far as I know) since I can't modify the response after the call.
I tried redirecting a response using but didn't work since I'm getting an telling me about the response was already committed or something like that.

I've also tried adding an block in my web.xml using a web servlet as the location but apparently that does not work for unsupported methods and invalid headers
(tried using a random string as request method; also tried as an invalid header).

Is there a way to create a general "filter" mechanism where I can modify the response code and message when there's a HTTP error code response?
 
Saloon Keeper
Posts: 7174
166
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I've tried using and found out that that won't work (as far as I know) since I can't modify the response after the call.


Modifying the response after it has been filtered is certainly possible. A quick search finds this example: https://www.codejava.net/java-ee/servlet/how-to-modify-http-response-using-java-filter
 
daniel march
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Moores wrote:

I've tried using and found out that that won't work (as far as I know) since I can't modify the response after the call.


Modifying the response after it has been filtered is certainly possible. A quick search finds this example: https://www.codejava.net/java-ee/servlet/how-to-modify-http-response-using-java-filter



Hi, I've already seen that, but I also want to modify the HTTP status code returned, not just the content.
 
Tim Moores
Saloon Keeper
Posts: 7174
166
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No problem, HttpServletResponseWrapper has methods to handle the status code.
 
Sheriff
Posts: 22510
122
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is some buffering involved, but in general you won't be able to add, remove or change headers once the response body has been set.

if you want to possibly discard the original response, the best way is probably to indeed make use of HttpServletResponseWrapper. By default it delegates to the original HttpServletResponse, but you can sub class it to do anything you want. In this case you probably want to do something like this:
  • Let getOutputStream return a ByteArrayOutputStream and getWriter return a PrintWriter wrapped around a StringWriter. The ByteArrayOutputStream and StringWriter should be instance fields, and you should ensure that only one of the two methods can be called (mandated by ServletResponse).
  • Let all headers be captured in a Map<String, List<Object>>, otherwise you won't be able to remove any. The values should only be String, Integer or Long (for Date), you can use the type to call the correct methods when copying headers to the original response.
  • The status can be set by the already existing functionality.


  • In your filter, you should do something like this:

    The performance will be worse because you're writing the content twice (first to MyResponse, then to the actual response), but if you need to be able to discard the content then you just can't write it to the original response just yet. Once written to that response you can't take it back anymore.
     
    Rob Spoor
    Sheriff
    Posts: 22510
    122
    Eclipse IDE Spring VI Editor Chrome Java Windows
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I was starting to write such a buffered HttpServletResponse class, when I found out that it's already possible with the current API.

    ServletResponse, and by extension HttpServletResponse, has the following methods:
    * setBufferSize(int)
    * getBufferSize()
    * flushBuffer()
    * resetBuffer()
    * reset()

    By setting a larger buffer, the servlet container must refrain from writing anything until the buffer size is reached or flushBuffer is called. Before that occurs, you can clear the body only with resetBuffer, or clear everything with reset().

    If you call reset(), you can call getWriter() or getOutputStream(), even though the other was called already. (Until you call reset() again, calling the other will again throw an exception.) No such statement is made for resetBuffer, so assume that it only resets the content of the writer / output stream, not the state of which one is called.

    Removing headers is impossible using the API unless you call reset(), so if you want to remove only some headers, you'll have to extract them first (using getHeaderNames() and getHeader(String) / getHeaders(String)), then re-add those you want.
     
    reply
      Bookmark Topic Watch Topic
    • New Topic