March 29, 2020
Estimated Post Reading Time ~

How to Customize Sling Model Exporter in AEM 6.3

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

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();
}
}


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.