Over a million developers have joined DZone.

Refining Redirect Semantics in the Servlet API [Snippet]

DZone's Guide to

Refining Redirect Semantics in the Servlet API [Snippet]

This simple, quick lesson in header management will help ensure your HttpServletResponse.sendRedirect() method returns the right HTTP status code.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

This post is bikeshedding, but as bikeshedding goes, it’s very important to write about it.

In web applications, it’s necessary to prevent impatient users from POSTing the same data over and over again — for example, to avoid the pain of putting the same item into the basket multiple times because of a browser refresh.

To implement that, there’s a good practice called the POST/redirect/GET pattern:

Image title

This week, I read (again) the list of HTTP status codes. In particular, the following specific snippet drew my attention:

302 Found

This is an example of industry practice contradicting the standard. The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302 with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307 to distinguish between the two behaviours. However, some Web applications and frameworks use the 302 status code as if it were the 303.

303 See Other (since HTTP/1.1)

The response to the request can be found under another URI using the GET method. When received in response to a POST (or PUT/DELETE), the client should presume that the server has received the data and should issue a new GET request to the given URI.

Unfortunately, the HttpServletResponse.sendRedirect() method returns the status code 302 instead of 303. Hence, it shouldn’t be used when implementing the above pattern. But how to do it then?

Simply go down one abstraction level and manage headers manually:

class FooServlet: HttpServlet() {

    override fun doPost(req: HttpServletRequest, resp: HttpServletResponse) {
        // Do stuff here
        resp.addHeader("Location", "/bar")

This achieves the desired result.

Image title

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

java ,http status codes ,servlet api ,redirect semantics ,post redirect get

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}