views:

704

answers:

1

Hello chaps,

I'm working on a web app that uses Jersey. I'm trying to implement a get-after-post sort of thing using a URIBuilder and a seeOther response. The aim is to redirect to the same URI the browser is already on, but to force a GET. It works a bit like this:

  1. Request comes in via PUT
  2. PUT request processed
  3. SeeOther response returned

What should happen is that the browser picks up the 303 See Other and performs a GET on the URI it receives. Unfortunately, what's happening is that it performs a PUT on the URI instead (as far as I can tell) and the PUT sends it back to Step 1. above, causing a redirection loop.

Any ideas what's going wrong here?

   private Response giveSeeOther(){
  /*Get the base URI builder*/
  final UriBuilder uriBuilder = m_uriInfo.getBaseUriBuilder();

  /* Some stuff to create the URI */
  final Map<String, Object> parameterMap = new HashMap<String, Object>();
  parameterMap.put("uid", getUid());

  final URI redirectUri = uriBuilder.path(SomeObject.class).
                                     path(SomeObject.class, "get").
                                     buildFromMap(parameterMap);

  /* See Other (303) */
  return Response.seeOther(redirectUri).build();}

That's the code for the see other method. I'm not sure what other code you might want to see, but let me know.

+1  A: 

You need to use a 301 HTTP response code instead.

By using 303, your POST request is maintained, and redirected accordingly. By using 301, your request is "Moved permanently" via GET.

For other readers who might wonder why someone wants to do this, it's to prevent the user from submitting their POST data more than once by using the "Reload" function of their web browser (which users with "rotten communications" problems often do) to reload the "thank you" page that may not have loaded completely.

Hint: When you redirect in this manner, if you're not using cookies to ensure information gets to your "thank you" page, then you'll need to add one or more parameters to your request in the same way a regular GET form will. For example, if the order ID number is 82838, you can pass it along to your "thank you" page like this:

http://www.example.com/order/thank-you.pl?orderid=82838

There are obvious potential security issues with this which are easily resolved by having your "thank you" page code check that the order ID actually belongs to the currently logged in user before it displays the order status (I assume you wish to include order status information on that "thank you" page -- in this case, it's also nice to include a "Refresh" button {or link} for the user to check up on the order status if it's something that progresses in the short term over a number of steps).

I hope that's helpful to you.

Randolf Richardson