Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Use the Sling Models API

DZone's Guide to

How to Use the Sling Models API

In this post, Francisco Ribeiro will explain how you can change your contact list application to use the Sling Models API.

Free Resource

Learn how API management supports better integration in Achieving Enterprise Agility with Microservices and API Management, brought to you in partnership with 3scale

In this post, we will change our contact list application to use the Sling Models API. You can see the first two posts about the app here and here.

By using the AdapterFactory, we can adapt Sling objects to our model objects. It is simple, but we need to have a lot of boilerplate code. The Sling Models bundle allow us to map the Sling objects to our Model objects. It is annotation driven and has a CDI-like style. You can check the documentation here.

Setting Up Sling Models in Our Project

The first thing we need to do in order to use the sling models in our core project is add the required dependencies in our pom.xml.

You can see them below:

<-- Sling Models API --> 
<dependency>
    <groupId>org.apache.sling</groupId>
    <artifactId>org.apache.sling.models.api</artifactId>
    <version>1.2.2</version>
    <scope>provided</scope>
</dependency>
<!-- javax.inject API -->
<dependency>
    <version>1.0</version>
    <groupId>org.apache.geronimo.specs</groupId>
    <artifactId>geronimo-atinject_1.0_spec</artifactId>
    <scope>provided</scope>
   </dependency> 

The first dependency is to allow us to use the Sling Models API and the second one is to use the annotations from javax.inject package.

The second step is to add the following instructions on the maven-bundle-plugin:

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions> 
    <version>3.0.0</version> 
    <configuration> 
        <instructions> 
            <Sling-Model-Packages> 
              com.xicojunior.contacts.models 
            </Sling-Model-Packages> 
        </instructions> 
    </configuration> 
</plugin> 

With these instructions, we set which package will contain our Sling Model POJOs.

After this first set-up, let’s code.

Creating Our First Sling Model Class

To set up our Sling Model class, we need to add only some annotations to our POJO. For our first example, we will change the Contact class. It will be like below:

@Model(adaptables=org.apache.sling.api.resource.Resource.class) 
public class Contact { 
  
    @Inject 
    private String name;
  
    @Inject 
    private String email;
  
    @Inject 
    private String phone; 
  
    @Inject 
    private String address; 

Basically, we define that our class will be a Sling Model by using the @Model annotation. In that annotation, we define the adaptable class, in this example Resource, so that we can adapt an instance of Resource to a Contact instance.

Then, we use the @Inject annotation to inject the node properties into the object attributes. The class properties have the same name as the node properties. So, when we deploy our bundle and use:

resource.adaptTo(Contact.class); 

...it will inject the properties which name matches with the annotated properties in the class.

Great, but if we remember our last posts, it is missing the contact image. The image is a child node under the contact node. For this, we will use some new annotations. Let’s see how to inject the child node into our class:

@ChildResource @Named("contactImage") 
private Resource contactImageResource; 

private String contactImage; 

@PostConstruct 
public void init() { 
    this.contactImage = contactImageResource.getPath(); 
} 

Let’s explain what we’ve done in the code above:

We used the @ChildResource in order to inject a child resource of the resource being adapted from. As the node name is not the same as the class property, we used the @Named with the node name. This way, we inject the node as a Resource in our class. But in our JSP, we only want the Resource path in order to display the image on the page, the JSP uses the contactImage property.

In order to keep the same attribute and not change the JSP, we created the init method and annotated it with @PostConstruct. With this annotation, we are saying that this method will be executed after the object is instantiated. In our example, it basically set the contactImage property with the contact image resource path.

Great! Now we can adapt the contact nodes to our Contact class with much less code.

Now we need to change our ContactList to use the Sling Models API.

Changing the ContactList Model Class

In the next step, we are going to change our ContactList class to be a Sling Model. It is very simple. Basically, we needed to add three annotations, as we can see below:

@Model(adaptables=SlingHttpServletRequest.class) 
public class ContactList { 
  
    @Inject @Via("resource") 
    private List<Contact> contacts; 

We added the @Model now having SlingHttpServletRequest as the adaptable. This class only holds the Contacts created. To inject the contact list, we just needed to add the @Inject in the contacts property. With the @Inject annotation, we can also inject a list of child resources. In our case, it will inject all child nodes of the contacts node.

One other thing we need to do is to add the @Via annotation. This annotation indicates that the injection should be done via a JavaBean property of the adaptable, in our example:

slingRequest.getResource() 

...and as we turned our Contact class into a Sling Model, we don’t need to adapt from the child Resources; the Sling Models API does that for us automatically.

Conclusion

The Sling Models API provides us a very simple way to convert Sling Objects into our model classes. In this post, we showed only some of the features provided by the API. It has a lot more to features that make our work a lot easier..

The complete code used in this post is on GitHub. In order to deploy it, you just need to do the following:

git clone https://github.com/fjunior87/sling-contact-list.git
cd sling-contact-list
git checkout sling_models
mvn clean install -P autoInstallBundle 

...and access the application.

http://localhost:8080/contactsapp.html 

To create the nodes you need to be authenticated (so, before using the application) please log in on the page:

http://localhost:8080/.explorer.html 

That’s it for today. I hope you enjoyed this.

Thanks and see you in the next post.

Unleash the power of your APIs with future-proof API management - Create your account and start your free trial today, brought to you in partnership with 3scale.

Topics:
integration ,apis ,sling models ,nodes

Published at DZone with permission of Francisco Ribeiro, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}