Question

It seems like Sling expects every form POST to modify the JCR. So the expected/standard behavior would be a POST-redirect-GET, which is fine for most things. However, I need to be able to POST to AEM and then use the data in that POST to create a rendered result. Our use of AEM is stateless and so I don't want to carry the POST'd data in Session in order to utilize it in a subsequent GET.

Some have recommended putting the POST'd data in Browser sessionStorage, but that doesn't have broad enough support to be sufficient.

As far as I can tell there is no way for Sling in AEM to take a POST and produce a rendered result.

Here is a screenshot of what a POST produces in the page/resourceType component and in any Sling included jsp's that happen to be involved in the rendering.

enter image description here

I have tried things like using the "nop" operation.

<input type="hidden" name=":operation" value="nop" />

But either way all servlets think a POST is happening and don't render properly.

There is the option of creating a custom servlet, to handle the POST, but then how do you render the templated output and change the request so that all the components think they are serving a GET?

UPDATED: Here is a screenshot of the "nop" POST.jsp result. enter image description here

Was it helpful?

Solution

What you can do is create a POST.jsp file in the appropiate resourceType.

If your POST request go to /content/yourapp/something, which has a resourceType: your/app/example. Then you can create a file /apps/your/app/example/POST.jsp with whatever render you wish. You can even include your default rendering script in the POST.jsp file if you need it to be rendered the same as the GET requests.

The other option is to use a servlet registered for POST requests and internally use the SlingRequestProcessor service. That service allow you to programmatically process a request through Sling. You can use a SlingRequestWrapper to wrap your request and override getMethod() to return "GET". That should process the request as if it was a GET request.

OTHER TIPS

This sounds like a somewhat funky use case, IIUC you are using a large request parameter P to drive the rendering?

Using a custom POST servlet should work, if you use something like slingRequest.getRequestDispatcher(resource).forward(request, response) where request is a wrapper around the actual request, where request.getMethod() returns GET. You can then store your P data in request attributes.

The SlingHttpServletRequestWrapper class can be used to create such wrappers.

Creating a custom servlet to handle a post could be an idea. After successfull write you could redirect to the modified resource - simple 302.

The other solution that comes to my mind is a custom Filter that would do the same. However, since AEM expects to get 200 instead of 302, it would be good to tell by atrribute or parameter that this POST needs to be redirected. Otherwise some of the AEM UI functionalities could brake. This is a quick example of an idea. You would probably need to write something more sophisticated.

@Component(immediate = true)
@Service
@Properties({
    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Desc"),
    @Property(name = Constants.SERVICE_VENDOR, value = "Company name"),
    @Property(name = Constants.SERVICE_RANKING, intValue = RedirectFilter.RANKING),
    @Property(name = "filter.scope", value = "request") })
public class RedirectFilter implements Filter {

public static final int RANKING = -1000; // low ranking

@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}

@Override
public void destroy() {
}

@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
        throws IOException, ServletException {
    if (request.getParameter("redirect").equals("true")) {
        ((SlingHttpServletResponse) response).sendRedirect(((SlingHttpServletRequest)request).getRequestURI());
    }
}

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top