Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AEM 6.1 Sightly basic form submit and redirect to same page

Tags:

aem

sling

sightly

I am trying to do the following on AEM 6.1:

  1. Develop a simple form (3 input fields)
  2. Process the submitted values,
  3. And redirect to the same page with processed values/result

I am able to submit the values to a servlet, and process them (business logic), and the result to a requestparamter so i can retrieve them on the UI. But i am stuck at these:

  1. Redirecting to the same page
  2. And retrieving the request parameters and display them using Sightly.

Code Snippets: Servlet

@SlingServlet(
methods = { "POST","GET" }, 
name="com.tti.tticommons.service.servlets.LeadTimeTrendsServlet",
paths = { "/services/processFormData" }
)
public class TTICommonServlet extends SlingAllMethodsServlet{   
...
@Override
protected void doPost(SlingHttpServletRequest request,SlingHttpServletResponse response) throws ServletException,IOException {
  String result;
  try {
        Enumeration<String> parameterNames = request.getParameterNames();
        Map<String, String> formParametersMap = new HashMap<String, String>();
        while (parameterNames.hasMoreElements()) {
            paramName = parameterNames.nextElement();
            paramValue = request.getParameter(paramName);
            .......
            .......
       }

       request.setAttribute("result",result);

       response.sendRedirect("/content/ttii/en/**posttest.html**");
    }
}

Can anyone please help on ho to retireve the above "result" in posttest.html using sightly.

like image 726
Suren Konathala Avatar asked Jul 16 '15 12:07

Suren Konathala


2 Answers

After lot of research and several trials, i finally had the code working. I had to pick up related info from several answers in stackoverflow. Thanks to all the authors. Posting my solution here so beneficial for others.

Result Form with response from webservice:

enter image description here

Process flow

  1. Submit form data to Servlet's POST method
  2. In Servlet, get the values entered by the user from the request
  3. Make the necessary webservice calls. Get the response(json)
  4. I added the response-json as a parameter to the request
  5. Using Wrapper, forward to the necessary page
  6. Define a WCMUse class for use with Sightly.
  7. Assign the 'request' to the Use-class and process it there
  8. Use the assigned values from the Use-class to the UI using sightly

Code snippets - HTML

  <form name="userRegistrationForm" method="post" action="/services/processFormData">

<input type="hidden" name=":redirect" value="posttest.html" />
<input type="submit" title="Submit" class="btn submit btn-success" value="Submit" tabindex="25" name="bttnAction">

<div data-sly-use.model="${'com.abccommons.service.helpers.PostServiceHelper' @ slingreq=request }">
**${model.getRawJson}**
</div>

Code snippets - Servlet

@SlingServlet(
label = "ABC - Common Servlet", 
metatype = true, 
methods = { "POST" }, 
name="com.abccommons.service.servlets.ABCPostServlet",
paths = { "/services/processFormData" }
)
public class ABCPostServlet extends SlingAllMethodsServlet{ 

@Override
protected void doPost(SlingHttpServletRequest request,SlingHttpServletResponse response) throws ServletException,IOException {  
    log.info("\n\n----- ABCPostServlet POST: ");        

    String paramName;
    String paramValue;
    String osgiService="";

    try {
        Enumeration<String> parameterNames = request.getParameterNames();
        Map<String, String> formParametersMap = new HashMap<String, String>();
        while (parameterNames.hasMoreElements()) {
            paramName = parameterNames.nextElement();
            paramValue = request.getParameter(paramName);

            if (paramName.equals("osgiService")) {
                osgiService = paramValue;
            } else if (paramName.equals(":cq_csrf_token")) {
                //TODO: don't add to the map
            } else if (paramName.equals("bttnAction")) {
                //TODO: dont' add to the map
            } else {
                //log.info("\n---ParamName="+paramName+", value="+paramValue);
                formParametersMap.put(paramName, paramValue);                            
            }
        }           

        String parametersInJSON = JSONHelper.toJson(formParametersMap);
        log.info("\n\n----------- POST paramters in json="+parametersInJSON);

        String json = webServiceHelper.getJSON(osgiService, parametersInJSON, request, response);
        log.info("\n\n----------- POST json from web service="+json);

        request.setAttribute("jsonResponse",json);

        //String redirectPage =  request.getParameter(":redirect");
        //RequestDispatcher dispatcher = request.getRequestDispatcher("/content/en/"+redirectPage);
        RequestDispatcher dispatcher = request.getRequestDispatcher("/content/en/postformtest.html");
        GetRequest getRequest = new GetRequest(request);
        dispatcher.forward(getRequest, response);            
    } catch (Exception e) {
        log.error("SlingServlet Failed while retrieving resources");
    } finally {
       //TODO
    }         
}

/** Wrapper class to always return GET for AEM to process the request/response as GET. 
*/
private static class GetRequest extends SlingHttpServletRequestWrapper {
    public GetRequest(SlingHttpServletRequest wrappedRequest) {
        super(wrappedRequest);
    }

    @Override
    public String getMethod() {
        return "GET";
    }
}    

Code snippets - PostServiceHelper - WCMUSe class

public class PostServiceHelper extends WCMUse {
protected final Logger log = LoggerFactory.getLogger(PostServiceHelper.class);

private SlingHttpServletRequest httpRequest;

private String rawJson;

@Override
public void activate() throws Exception {
    log.info("\n\n========= PostServiceHelper.activate():"+get("slingreq", SlingHttpServletRequest.class));
    this.httpRequest = get("slingreq", SlingHttpServletRequest.class);
    //this.resourceResolver = getResourceResolver();        
    //log.info("\n\n========= getRequest()="+getRequest()); 

    SlingHttpServletRequest tRequest;

    Set<String> keys = new HashSet<String>();
    Enumeration<?> attrNames = this.httpRequest.getAttributeNames();
    while (attrNames.hasMoreElements()) {
        String attr = (String) attrNames.nextElement();            
        //log.info("\n--- Key="+attr);

        if (attr.equals("jsonResponse")) {
            this.setRawJson((String)this.httpRequest.getAttribute(attr));
            //log.info("\n---rawJson is SET with : "+this.rawJson);
        }
    }
}

 public void setRawJson(String json) {
    this.rawJson = json;
}   

public String getRawJson() {
    return this.rawJson;
}
}
like image 183
Suren Konathala Avatar answered Sep 18 '22 22:09

Suren Konathala


This is actually a rather tricky pattern to achieve in Sling. You may be better served by submitting the form asynchronously and updating your HTML dynamically via JavaScript.

If you do need to submit your form in the manner you specify, then your servlet needs to produce the HTML response. To produce a response made up of a rendering of the page identified by the requested path your servlet will need to dispatch the request to the appropriate rendering mechanism. You can reference Get JSP output within Servlet in AEM for information concerning how that can be accomplished. Upon dispatch your page and its components should have access to the submitted form values as well as the attributes set on the request.

like image 31
Paul Michelotti Avatar answered Sep 18 '22 22:09

Paul Michelotti