Sean, The SlingPostServlet actually sets the Location header of the response based on the content that was created/modified by the request so that the browser is obliged to issue a new GET request for the subsequent resource if it is a synchronous form post, while ajax client code is free to ignore it without making a call to render the resource.
Ideally (from a REST perspective, that is), your POST request would not be internally dispatched as a GET request, but would instead make use of the Location header in the response to link to the html-rendered confirmation resource. GET renditions are typically designed with reverse proxy caching in mind, whereas POST responses are generally not cached. This can result in unforseen performance impacts when GET responses are returned for POST requests. As you point out, using redirects can be cumbersome if you are passing a lot of contextual data encoded in the Location url, and doing so may be incompatible with your security restrictions. Instead, the proper route may actually be to persist the post context as a "form/confirmation" resource that serves as the Location header target that actually exists in the repository for some period of time. By giving the context a concrete resource path, you expose its html rendition as a cacheable document that can even be bookmarked by the end user for future reference for confirmation numbers, submission dates, context-sensitive links, etc. It also puts the application in control of the experience of confirming a form re-submission, instead of leaving it up to the browser when a POST request returns html without redirecting. Obviously, blindly allowing anonymous requests to create nodes in the repository is itself a significant invitation for a DOS attack, so I don't mean to suggest that this route is easy or without additional architectural considerations, but I think it makes the site experience more predictable from the client perspective. Mark Adamcin Acquity Group Sent from a mobile device. On Feb 26, 2013, at 6:48 PM, Sean Steimer <[email protected]> wrote: > Is there a recommended approach to handle a POST request in sling where the > eventual html response rendered to the user depends heavily on the original > context of the request? > > I've run across this problem in a few different scenarios, but the general > flow looks something like this: > - user is presented with an html form > - form is submitted via HTTP post, which is handled by a servlet > - servlet process the data, which involves perhaps complex logic such as > calling some external service > - user then should see a thank you page confirming successful submission, > and the thanks you page needs to also include info about what was submitted > (ie. order details in an eCommerce scenario) > > That last step becomes a problem because of the way post requests are > handled by the sling post Servlet. If I simply do > slingRequest.getRequestDispatcher().forward() the request method remains > post, and the thank you page doesn't render as expected. I've gotten > around this before by using sendRedirect() and setting cookies, or passing > along url parameters, but when there is a large amount of data involved, > this becomes less than ideal, plus you are adding an extra server > round-trip. > > I've also thought about using a custom ServletRequestWrapper that overrides > getMethod() to always return "GET", but that seems Hacky at best. > > Are there common approaches/patterns/helper classes to make this work that > I'm just not aware of? > > FWIW, my work in this areas has been with CQ, but my understanding is that > the limitations I'm running into are based on sling POST servlet handling, > hence why I'm asking the questions here.
