You have already seen the magic of Sling Model Exporters in my previous blog.But there is something left with Sling Model Exporters which I would like to continue in this blog.
I have mentioned in the previous blog that we can have custom exporters in
Sling Model Exporters.
So let’s have some examples of creating custom exporters.Here I am going to demonstrate
“GSON” and “JAXB” as two custom exporters in the concept of Sling Model Exporters.
ModelExporter Interface
To create a custom exporter, we need to create a service that implements ModelExporter
with these three methods:
Fig - Model Exporter Interface |
Here we will see two implementations of ModelExporter Interface:
- ModelExporter Example: GSON
@Component(service = ModelExporter.class)
public class NewExporter implements ModelExporter {
public <T> T export(Object model, Class<T> clazz,
Map<String, String> options)
throws org.apache.sling.models.factory.ExportException {
return (T) new Gson().toJson(model);
}
public String getName()
{
return "gson";
}
public boolean isSupported(Class Model1)
{
return true;
}
}
|
And then this “gson” exporter can be used in the Sling Model like this.
@Model(adaptables = Resource.class, resourceType = {"weretail/components/structure/page"}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = "gson", selector = "test",extensions = "json")
public class Model3 {
@ValueMapValue(name = "jcr:title")
private String title;
public String getTitle()
{
return title;
}
}
|
Fig - Response in JSON format using GSON Exporter |
- ModelExporter Example: JAXB
@Component(service = ModelExporter.class)
public class NewExporter implements ModelExporter {
public <T> T export(Object model, Class<T> clazz,
Map<String, String> options)
throws org.apache.sling.models.factory.ExportException {
StringWriter sw = new StringWriter();
try {
JAXBContext jaxbContext =
JAXBContext.newInstance(model.getClass());
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(model, sw);
} catch (JAXBException e) {
e.printStackTrace();
}
return (T) sw.toString();
}
public String getName() {
return "jaxb";
}
public boolean isSupported(Class Model1) {
return true;
}
}
|
And then this “jaxb” exporter can be used in the Sling Model like this.
@Model(adaptables = Resource.class, resourceType = {"weretail/components/structure/page"}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = "jaxb", selector = "test",extensions = "xml")
@XmlRootElement
public class Model3 {
@ValueMapValue(name = "jcr:title")
private String title;
@XmlElement
public String getTitle()
{
return title;
}
}
|
Fig - Response in XML format using JAXB Exporter |
Let's have a demonstration video on Custom Sling Model Exporter:
Tips and Trick of Sling Model Exporters
- Sling Model Exporters internally works on sling:resourceSuperType as well.If you have defined a resourceType in sling Model Exporter, it will check the resourceType of a request, if it doesn’t present it will go to its sling:resourceSuperType.
- Sling Model Exporters can be adapt using Modelfactory Interface.
You can see the example here:
public class ResolveServletUsingPath extends SlingSafeMethodsServlet {
@Reference
private ModelFactory modelFactory;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
Resource resource = request.getResourceResolver().getResource("/content/we-retail/ca/en/experience/jcr:content");
try {
response.getWriter().print( modelFactory.exportModelForResource(resource,"jaxb",Model3.class,new HashMap<>()));
} catch (ExportException e) {
e.printStackTrace();
} catch (MissingExporterException e) {
e.printStackTrace();
}
}
|
Let's have a demonstration video on Tips and Tricks of Sling Model Exporters:
If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com
Hope it will help you guys !!
Thanks and Happy Learning.
Hi Team ,
ReplyDeletePlease help on this. I couldn't run the below servlet.
package com.mst.hackathon.core.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Repository;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
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.resource.ResourceResolverFactory;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SlingServlet(paths="/bin/mySearchServlet", methods = "GET", metatype=true)
public class MstHackServlet extends org.apache.sling.api.servlets.SlingAllMethodsServlet {
@Reference
private SlingRepository repository;
@Reference
public void bindRepository(SlingRepository repository) {
this.repository = repository;
}
protected final Logger log = LoggerFactory.getLogger(this.getClass());
@Override
protected void doGet(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
Map param = new HashMap();
param.put(ResourceResolverFactory.SUBSERVICE, "datawrite");
resp.setContentType("application/json");
String keys[] = repository.getDescriptorKeys();
log.error("Sling Folder with MstHackServlet>>>>>..MstHackServlet" );
JSONObject jsonobject = new JSONObject();
for(int i=0;i<keys.length;i++) {
try {
jsonobject.put(keys[i], repository.getDescriptor(keys[i]));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
resp.getWriter().println(jsonobject.toString());
}
}
You are using some SCR annotations and some OSGI annotations in one class. Either use completely SCR or OSGI DS annotations.
DeleteHi Shivani,
DeleteCan you explain the above code and list out OSGI annotations and SCR annotations on the above code
I got the below error.
ReplyDeleteThe resource given by path ' /bin/mySearchServlet ' does not exist. Therefore no resource type could be determined!
Candidate servlets and scripts in order of preference for method GET:
com.day.cq.commons.servlets.NonExistingDispatcherServlet (OptingServlet)
org.apache.sling.servlets.get.impl.DefaultGetServlet
org.apache.sling.jcr.webdav.impl.servlets.SlingWebDavServlet
Hi Thanks for the tutorial it was very helpul. Do you know how can I change the character encoding in the response of the model exporter. Right now I'm using Jackson as exporter
ReplyDeleteNice article for Sling Model information.
ReplyDeleteAlso found one more article for Adobe AEM with defined information
https://aemintroduction.blogspot.com/
Hi, I am using JAVA 11 and it gives me this error.
ReplyDeleteUnable to make private java.lang.module.Configuration() accessible: module java.base does not "opens java.lang.module" to unnamed module @1c77bbe7
Anyone encountered the same thing?