Expand my Community achievements bar.

SOLVED

Save form data in AEM Repository node

Avatar

Level 2

I am trying to save form data in an AEM repository node (CRXDE Lite) and I am trying to figure out how to do so. I know that the standard form component allows you to save the data in a folder called "user-generated", but when data saves, the data is stored in a folder inside of user-generated that is about 12 random numbers. I need to be able to name that folder appropriately so that I can get that data for later use. What can I do?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@df94 - that's basically part of the OSGI bundles and for that you first need to understand how OSGI bundles works in AEM in relations with AEM application.

You may go through few blogs about it.

OSGI Bundle - https://www.techinnovia.com/osgi-bundles/

Sling Model - https://www.techinnovia.com/sling-model/

 

View solution in original post

7 Replies

Avatar

Community Advisor

Hi @df94 ,

You can implement custom logic to save form data in repository by implementing

  • Sling Model
  • Servlet
  • OSGi Services

per your requirement.

Additionally, refer one of the following example code snipper for the same.

In AEM data is stored in JCR in the forms of nodes and properties, So to save data in JCR, you need to create nodes or/and properties. In your servlet get the data and create node/property using JCR Node.

Please check below snippet, it is just for demonstration.

  1. Create Component and add below code in HTL
    HTL
    <form id="submitForm" method="post" action="/apps/my/servlets/path/create"> 
    <input type="text" name="name" value="" />
    <input type="text" name="email" value="" />
    <input type="text" name="title" value="" />
    <input type="text" name="phone" value="" />
    <input type="submit" value="Submit"/>
    </form>
  2. Create Servlet which is responsible to handle form request and save data in JCR node.
    Servlet
    package com.test.servlet; 
    import com.day.cq.commons.jcr.JcrUtil;
    import org.apache.felix.scr.annotations.Component;
    import org.apache.felix.scr.annotations.Properties;
    import org.apache.felix.scr.annotations.Property;
    import org.apache.felix.scr.annotations.Reference;
    import org.apache.felix.scr.annotations.sling.SlingServlet;
    import org.apache.sling.api.SlingHttpServletRequest;
    import org.apache.sling.api.SlingHttpServletResponse;
    import org.apache.sling.api.servlets.SlingAllMethodsServlet;
    import org.apache.sling.jcr.api.SlingRepository;
    import org.osgi.service.component.ComponentContext;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import javax.jcr.Node;
    import javax.jcr.RepositoryException;
    import javax.jcr.Session;
    import javax.servlet.ServletException;
    import java.io.IOException;
    import java.io.PrintWriter;

    @Component(immediate = true, metatype = true, name = "com.test.CreateServlet", label = "Create Servlet", description = "Test creation servlet")
    @SlingServlet(methods = { "POST" }, paths = "/apps/my/servlets/path/create", generateComponent = false)
    @Properties({ @Property(name = "service.description", value = "CreateServlet"), @Property(name = "service.vendor", value = "My Vendor") })
    @SuppressWarnings({ "serial", "unused" })
    public class CreateServlet extends SlingAllMethodsServlet {
    private static final String CREATE_PATH = "/content"; /// Set the base path here
    private static final Logger log = LoggerFactory.getLogger(CreateServlet.class);

    @Reference private SlingRepository repository;

    @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
    //We are not using this atm.. but you could
    }

    @Override protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
    ResourceResolver resourceResolver = request.getResourceResolver();
    Session session = resourceResolver.adaptTo(Session.class);
    String name = request.getParameter("name");
    String email = request.getParameter("email");
    String title = request.getParameter("title");
    String phone = request.getParameter("phone");

    PrintWriter out = response.getWriter();
    try {
    Node firstProduct = JcrUtil.createPath(CREATE_PATH + "/" + name , "cq:Page", session);
    Node firstSubProduct = JcrUtil.createPath(firstProduct.getPath() + "/subproduct1", "nt:unstructured", session);
    Node secondSubProduct = JcrUtil.createPath(firstProduct.getPath() + "/subproduct2", "nt:unstructured", session);
    firstSubProduct.setProperty("email", email);
    firstSubProduct.setProperty("title", title);
    secondSubProduct.setProperty("email", email);
    secondSubProduct.setProperty("title", title);
    session.save();
    out.println("That went well...");
    out.flush();
    out.close();
    }
    catch (RepositoryException e) {
    out.println("That went not so well...");
    out.flush();
    out.close();
    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
    }
    }

Hope that helps!

Regards,

Santosh

Avatar

Level 2

Is there anything else that I have to add to my code or in CRDXE Lite? I see that you said an OSGI Config, but I'm not sure how to do that.

Avatar

Correct answer by
Community Advisor

@df94 - that's basically part of the OSGI bundles and for that you first need to understand how OSGI bundles works in AEM in relations with AEM application.

You may go through few blogs about it.

OSGI Bundle - https://www.techinnovia.com/osgi-bundles/

Sling Model - https://www.techinnovia.com/sling-model/

 

Avatar

Community Advisor

I think, when you create a form, you get a option to set path for user-generated data

 

arunpatidar_0-1670419796402.png

 



Arun Patidar

Avatar

Community Advisor

the data is stored in AEM but for publish instance you have to provide write access otherwise it will not work.

If you want to take full of data then you need to write your own custom solution to store and retrieve data.

 

The above example is from core components o you can check what they offer, if that match your use case then use core component otherwise extend.

 

we don't know your full use case here, so don't know how you will use this data.



Arun Patidar

Avatar

Level 2

Is there a way to use this to store content with a name as opposed to random numbers? When I used it, it stored it as a folder with random numbers. Also, I'm using the data to make a page to show that I have the names from the form.