Ad Code

Saturday, August 26, 2017

Alternatives of Deprecated JSON API in AEM 6.3


Hello Everyone,

While working with a technology, we used to being habitual of an API and if someday in newer version it becomes deprecated, it just make us irritated.

So yes, I am talking about “org.apache.commons.json.* “. While writing a code in AEM 6.3, I came to know that ohhh… this has been deprecated now.

And if it is not there what are all alternatives for this. So AEM has some better alternatives now. AEM 6.3 now provides the support of Gson  and jackson as well and makes AEM development more easier.
Let’s talk about alternatives:
1. GSON
GSON.PNG
Fig - GSON Bundle in felix console
2. Jackson
Capture.PNG
Fig - JACKSON Bundle in felix console

Before going in detail with these two API’s we need to understand two terms:
Serialization: When Pojo classes or java objects can be converted into json, it is called serialization.
Deserialization: When json data is converted to java objects it is called deserialization. So serialization and deserialization are two basic functionalities, for which we need these API’s.
1. GSON:
Add maven dependency in your pom.xml
<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.3</version>
</dependency>

Serialization and Deserialization using GSON

The demonstration video of Serialization and Deserialization using GSON can be seen from here:

References to know more about GSON:
GSON Annotations

GSON provides some Annotations:
  1. @Expose:
  2. @SerializedName
  3. @Since @Until
  4. @JsonAdapter
The detailed description of all basic annotations will be in the demo video

References to know more about these annotations:


2.Jackson:
Add maven dependency in your pom.xml
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.8.4</version>
  <scope>provided</scope>
</dependency>

Serialization and Deserialization using Jackson

The demonstration video of Serialization and Deserialization using Jackson can be seen from here:


References to know more about Jackson API:

Jackson Annotations
Jackson provides much more annotations than GSON.
Jackson Serialization Annotation
  • @JsonAnyGetter

  • @JsonGetter

  • @JsonPropertyOrder

  • @JsonRawValue

  • @JsonValue

  • @JsonRootName

  • @JsonSerialize

Jackson Deserialization Annotations
  • @JsonCreator
  • @JacksonInject

  • @JsonAnySetter

  • @JsonSetter

  • @JsonDeserialize

Jackson Property Inclusion Annotations
  • @JsonIgnoreProperties
  • @JacksonInject

  • @JsonAnySetter

  • @JsonSetter


The detailed description of all basic jackson annotations will be in the demo video.


Jackson Vs GSON
To use both Libraries is quite easy but you must be thinking that when to use what?
Are there some specific scenarios where I should choose a particular Library?

So the answer is yes.
  • For converting small- or medium-sized lists, Gson provides a better response compared to Jackson.
  • For large lists, Jackson provides a better response than Gson.
  • Based on this results one can conclude that for converting small or medium size list to JSON one can use Gson for better performance.
table.PNG
Fig -  Complexity Comparison in GSON and JACKSON
So, When to use which API is up to the requirements.
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.

Sunday, August 20, 2017

Deep Dive on Sling Model in AEM 6.3 : Part-2


In our previous blog, we have already learned basics of sling models.But the magic of sling models is not over. We have more to know.
We have seen injector specific annotations of sling models in Part-1, except all these specific sling model Injectors we have some more annotations that help in Sling Models Development.
@Inject: This annotation is used to inject a property, resource, request anything.This is a generic annotation, which traverses all the sling model injectors based on service ranking.

@Model(adaptables = Resource.class)
public classTest {

  @Inject
  String path;

  public String getPath() {
      return path;
  }
}

@Named: If there is a need to change the getter of any attribute like (sling:resourceType, jcr:primaryType) @Named annotation helps to achieve this.

@Model(adaptables = Resource.class)
public class Test {

  @Inject @Named("sling:resourceType")
  String slingResourceType;

  public String getSlingResourceType() {
      return slingResourceType;
  }
}

@Default: A default value can be provided for Strings or primitive data types.If there is no value of that property, default value takes place.

@Model(adaptables = Resource.class)
public class Test {

  @Inject @Default(values = "/content/test")
  String path;

  public String getPath() {
      return path;
  }
}

@Optional and @Required: In the sling models, by default all the fields supposed to be required.Sometimes there is a need to mark them as optional and required specifically.So injector fields can be annotated with @Optional and @Required.

If a majority of @Injected fields/methods are optional, it is possible to change the default injection strategy by using adding defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL to the @Model annotation:

@Model(adaptables = Resource.class)
public class Test {

  @Inject @Optional
  String path;

  @Inject @Required
  String title;

  public String getTitle() {
      return title;
  }

  public String getPath() {
      return path;
  }
}
@Source: If you are using @Inject annotation and you want to specifically tell the sling engine that which specific injector you want to inject, you can use this annotation.All the specific injectors can also be used with @Source annotations.Using this annotation is equivalent to using injector specific annotation in a different way.

@Model(adaptables = SlingHttpServletRequest.class)
public class Test {

  @Inject  @Source("script-bindings")
  Page currentPage;

  public String getPath() {
      return currentPage.getPath();
  }
}
@Via : SlingHttpServletRequest has more objects than resource. Sometimes there is a need of using two injectors one from request and one from resource, Then we need to tell annotation explicitly that you are coming via resource.

@Model(adaptables = SlingHttpServletRequest.class)
public class TestModel {
   
   // Injects ResourcePath with Via annotation
   @ResourcePath(path = "/etc/social") @Via("resource")
   Resource resource;
   
   // Injects currentPage from ScriptVariable adaptable to Request
   @ScriptVariable
   Page currentPage;
}
@PostConstruct: The @PostConstruct annotation can be used to add methods which are invoked upon completion of all injections: This method automatically gets called when a sling model instance is created.
Note:The name of the method doesn’t matter, only it is matters that on which method the PostConstruct annotation exist.

@Model(adaptables = SlingHttpServletRequest.class)
public class Test {

 @Inject @Source("script-bindings")
 Page currentPage;
 
  String path;

 @PostConstruct
 protected void postMethod() {
     path = currentPage.getPath();
 }

 public String getPath() {
     return path;
 }
}
The Demonstration video on @Inject, @Named, @Default, @Optional, @Required, @Source, @Via and @PostConstruct:


@AemObject Annotation by ACS Commons Package

ACS Commons package provides one more injector specific annotation named @AemObject.This annotation provides the support of a lot of objects shown below:
aemObject.PNG
Fig- List of object in @AemObject annotation provided by ACS Common
This annotation is not the part of sling models, so if sling models itself has all your needed injectors, no need to go for it.But some Objects are not available with sling models like Tagmanager, WorkflowSession, WCMMode, at that time, this annotation can help you. Remember your project must have dependencies of ACS-Commons before using this annotation.

@Model(adaptables = SlingHttpServletRequest.class)
public class TestModel {

// Injects currentPage using ScriptVariable annotation
@AemObject
Page currentPage;

public String getPagePath() {
 currentPage.getPath();
}
}

List Injection From Child Resource(Since Sling Models Impl 1.0.6)
+- resource (being adapted)
|
+- content
   |
   +- subchild1
   |
   +- subchild

@Model(adaptables = Resource.class)
public classTest {

  @Inject
  List<Resource> content;
  
 public int getSize()
  {
      return content.size();
  }
}
Sling Adapter Framework
1.adaptTo: Apache Sling provides a way to adapt Sling related classes to our domain classes. The Resource and ResourceResolver interface provides the adaptTo method, which adapts the objects to other classes.
With the adaptTo API we can convert the Sling-related objects to our Model objects by using the AdapterFactory classes.
Test model = resource.adaptTo(Test .class)
As with other AdapterFactories, if the adaptation can't be made for any reason, adaptTo() returns null.
2.ModelFactory (Since1.2.0): Since Sling Models 1.2.0 there is another way of instantiating models. The OSGi service ModelFactory provides a method for instantiating a model that throws exceptions.There is no need of null checks and it is easier to see why sling model instantiation is failed. ModelFactory API provides a lot of methods, which can be efficiently used.

public class ModelServlet extends SlingSafeMethodsServlet {

@Reference
ModelFactory modelFactory;

@Override
protected void doGet(final SlingHttpServletRequest req,final SlingHttpServletResponse resp) throws ServletException, IOException {

 Resource resource = req.getResourceResolver().getResource("/content/community-components/en/tagcloud/jcr:content");

 Test test = modelFactory.createModel(resource, Test.class);
 resp.getWriter().println(test.getResourceType());
 resp.getWriter().println(modelFactory.canCreateFromAdaptable(resource, Test.class));
 resp.getWriter().println(modelFactory.canCreateFromAdaptable(req, Test.class));

}
}

@Model(adaptables = Resource.class)
public class Test {

 @Inject @Named("sling:resourceType")
  String resourceType;

  public String getResourceType()
  {
      return resourceType;
  }
}

The Demonstration video on @AemObject, List Injection and Adapter Framework:



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.