Article summary

Summary

Discusses how to create an Apache Sling Servlet that accepts UTF-8 encoded data that contains special characters such as ®. The Sling Servlet persists data that contains the special characters in the AEM JCR. This article also discusses how to configure the Sling Servlet so that authentication is not required. 

 

This article uses an Adobe Maven Archetype project to build an OSGi bundle. If you are not familiar with an Adobe Maven Archetype project, it is recommended that you read the following article: Creating your first AEM Service using an Adobe Maven Archetype project.

 

Digital Marketing Solution(s) Adobe Experience Manager (Adobe CQ)
Audience
Developer (intermediate)
Required Skills
Java, Maven, JCR, Sling
Tested On Adobe Experience Manager 5.5, 5.6

Introduction

In some some business use cases, you may have to post special characters, such as ®, to Adobe Experience Manager. Once posted to AEM, you can use special characters to set node properties, as shown in the following illustration.   

SpecialCRX2

By default, you cannot post strings to AEM that contain special characters. For example, you cannot run this CURL command to post special charactes to AEM.

curl -H "charset=utf-8" -u admin:admin -X POST --data "test=€ , Š , Œ , ™ , š , œ , ž" http://localhost:4502/content/mynodetest

If you attempt this command with CURL, wrong characters are inserted into AEM. That is, you will see: "Ç , è , î , Ö , Ü , £ , P , Ä , " instead of "€ , Š , Œ , ™ , š , œ , ž , Ž , Ÿ".

To successfully post special characters to AEM and use them to set node values in the AEM JCR, you have to create a custom Sling Servlet that handles UTF-8 (UCS Transformation Format—8-bit) encoded strings. This encoding type is a variable-width encoding that represents every character in the Unicode character set.

The Sling Servlet can decode the strings that contain special characters using Java application logic.

String id = java.net.URLDecoder.decode(request.getParameter("id"), "UTF-8");
String firstName = java.net.URLDecoder.decode(request.getParameter("firstName"),"UTF-8");

To post these special characters to the AEM Sling Servlet, encode the strings, as shown in this Java code example.

String val = java.net.URLEncoder.encode("cust®", "UTF-8");
String firstName = java.net.URLEncoder.encode("TOM®", "UTF-8");

Note:

If you are using other Restful clients to post data to AEM that contains special characters, encode the data to UTF-8 in the technology that you are using. For example, if you are using an ActionScript or a .NET Restful client, encode the data using the given technology.

This development article guides you through creating a Java application that posts data that contains special characters to an AEM Sling Servlet. It also walks you through how to create the AEM Sling Servlet. The AEM Sling Servlet is implemented as an OSGi bundle that is built using Declarative Services (DS) and Maven. DS is used to inject a ResourceResolverFactory instance into the service. The OSGi bundle is a managed component, which means that the OSGi service container creates the ResourceResolverFactory instance.

Create the client application that posts special characters to AEM.

The first step is to create an IntelliJ Maven Java project as shown here.

JavaMaven

Create an IntelliJ project by performing these tasks:

  1. Start IntelliJ IDEA.
  2. Click File, New Project.
  3. Select Maven Module.
  4. In Project Name, type PostSpecialChars.
  5. In Project Location, specify a location for your project. In this example, C:\PostSpecialChars is specified.
  6. In the Project SDK, specify the location to your Java SDK location.
  7. Click Next.
  8. Click Finish.  

Create the PostSC class

In your newly created project, create a Java class named PostSC. The PostSC class contains a Java main method that contains application logic that posts special characters to the AEM Sling Servlet. The value http://127.0.0.1:4502/bin/handleclaimSC represents the URL to the custom Sling Servlet.

When you develop the Sling Servlet, you specify /bin/handleclaimSC by using the @SlingServlet annotation value (this is shown later in this development article). The Sling Servlet is configured so authentication is not required. As a result, the Java application logic in the PostSC class does not contain authentication application logic.

The following Java code represents the PostSC class that contains application logic that posts special characters to the AEM Sling Servlet.

import java.util.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class PostSC {

    public static void main(String[] args) {

        try
        {

            //Specify the URL to the AEM Sling Servlet
            URL url = new URL("http://127.0.0.1:4502/bin/handleclaimSC");

            Map<String,Object> params = new LinkedHashMap<String,Object>();

            //Encode the special chars to post to AEM
            String val = java.net.URLEncoder.encode("cust®", "UTF-8");
            String firstName = java.net.URLEncoder.encode("Tom®", "UTF-8");
            String lastName = java.net.URLEncoder.encode("Blue®", "UTF-8");
            String address = java.net.URLEncoder.encode("157 NoWhere™", "UTF-8");
            String cat = java.net.URLEncoder.encode("Homeš", "UTF-8");
            String state = java.net.URLEncoder.encode("NYœ", "UTF-8");
            String details = java.net.URLEncoder.encode("Firež", "UTF-8");
            String date = java.net.URLEncoder.encode("April 2014ž", "UTF-8");
            String city = java.net.URLEncoder.encode("NY™", "UTF-8");

            params.put("id", val);
            params.put("firstName", firstName);
            params.put("lastName", lastName);
            params.put("address", address);
            params.put("cat", cat);
            params.put("state", state);
            params.put("details", details);
            params.put("date", date);
            params.put("city", "city");

            StringBuilder postData = new StringBuilder();
            for (Map.Entry<String,Object> param : params.entrySet()) {
                if (postData.length() != 0) postData.append('&');
                postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
                postData.append('=');
                postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
            }
            byte[] postDataBytes = postData.toString().getBytes("UTF-8");


            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setRequestMethod("POST");
          conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
            conn.setDoOutput(true);

            // Write data
            OutputStream os = conn.getOutputStream();
            os.write(postDataBytes);

            // Read response
            StringBuilder responseSB = new StringBuilder();
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

            String line;
            while ( (line = br.readLine()) != null)
                responseSB.append(line);

            // Close streams
            br.close();
            os.close();
           System.out.println("Done");

        }
        catch(Exception e)
        {
            e.printStackTrace() ;
        }
    }
}

Setup Maven in your development environment

You can use Maven to build an OSGi bundle that contains a Sling Servlet. Maven manages required JAR files that a Java project needs in its class path. Instead of searching the Internet trying to find and download third-party JAR files to include in your project’s class path, Maven manages these dependencies for you.

You can download Maven 3 from the following URL:

http://maven.apache.org/download.html

After you download and extract Maven, create an environment variable named M3_HOME. Assign the Maven install location to this environment variable. For example:

C:\Programs\Apache\apache-maven-3.0.4

Set up a system environment variable to reference Maven. To test whether you properly setup Maven, enter the following Maven command into a command prompt:

%M3_HOME%\bin\mvn -version

This command provides Maven and Java install details and resembles the following message:

Java home: C:\Programs\Java64-6\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"

Note:

It is recommended that you use Maven 3.0.3 or greater.  For more information about setting up Maven and the Home variable, see: Maven in 5 Minutes.

Next, copy the Maven configuration file named settings.xml from [install location]\apache-maven-3.0.4\conf\ to your user profile. For example, C:\Users\scottm\.m2\.

You have to configure your settings.xml file to use Adobe’s public repository. For information, see Adobe Public Maven Repository at http://repo.adobe.com/.

Create an Adobe Experience Manager archetype project 

You can create an Experience Manager archetype project by using the Maven archetype plugin. In this example, assume that the working directory is C:\AdobeCQ. 

plugin1

To create an Experience Manager archetype project, perform these steps:

1. Open the command prompt and go to your working directory (for example, C:\AdobeCQ).

2. Run the following Maven command:

mvn archetype:generate -DarchetypeRepository=https://repo.adobe.com/nexus/content/groups/public/ -DarchetypeGroupId=com.day.jcr.vault -DarchetypeArtifactId=multimodule-content-package-archetype -DarchetypeVersion=1.0.2 -DgroupId=com.adobe.aem.sc -DartifactId=claimsc -Dversion=1.0-SNAPSHOT -Dpackage=com.adobe.aem.sc -DappsFolderName=myproject -DartifactName="My Project" -DcqVersion="5.6.1" -DpackageGroup="My Company"

3. When prompted for additional information, specify Y. 

4. Once done, you will see a message like:

[INFO] Finished at: Wed Mar 27 13:38:58 EDT 2013
[INFO] Final Memory: 10M/184M

5. Change the command prompt to the generated project. For example: C:\AdobeCQ\claimsc. Run the following Maven command:
mvn eclipse:eclipse

After you run this command, you can import the project into Eclipse as discussed in the next section.

Add Java files to the Maven project using Eclipse

To make it easier to work with the Maven generated project, import it into the Eclipse development environment, as shown in the following illustration. 

PostSC

 

The next step is to add a Java file to the com.adobe.aem.sc package named HandleClaimSC. The Java class that you create in this section extends the Sling class named org.apache.sling.api.servlets.SlingAllMethodsServlet. This class supports the doPost method that lets you submit a file from the Java Swing client application. For information about this class, see Class SlingAllMethodsServlet.

The HandleClaimSC class uses Apache Felix SCR annotations to create the OSGi component. For information about Apache Felix SCR annotations, see http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html.

A ResourceResolverFactory instance is injected into the doPost method. This instance creates a Session instance that lets you persist the file into the AEM JCR. To inject a ResourceResolverFactory instance, you use the @Reference annotation to define a class member, as shown in the following example.

//Inject a Sling ResourceResolverFactory
@Reference
private ResourceResolverFactory resolverFactory;

You invoke the ResourceResolver object's adaptTo method to create a Session object, as shown here.

//Persist the Data into the AEM JCR
//Invoke the adaptTo method to create a Session
ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null);
session = resourceResolver.adaptTo(Session.class);

//Create a node that represents the root node
Node root = session.getRootNode();  

The Session object is used to retrieve JCR nodes and create new JCR nodes.   

Note:

When you open a JCR session, there is a reference to the JCR repository object. Every session will consume some memory unless the logout() method is called explicitly. If you do not call this call and create lots of sessions, you risk an out-of-memory exception by your JVM, which terminates the CQ instance. A single leaked session isn’t a problem, but if you have hundreds or thousands of leaked sessions, it might turn into a problem. For more information, see CQ development patterns – Sling ResourceResolver and JCR sessions

The HandleClaimSC Java class also uses a SlingServlet annotation:

@SlingServlet(paths="/bin/handleclaimSC", methods = "POST", metatype=true)

The paths property corresponds to the URL that you specify when posting values to this Sling Servlet. The Sling Servlet created in this development article is configured so that authentication is not required by using a Property annotation.

@Property(name = "sling.auth.requirements", value = "-/bin/handleclaimSC")

The following Java code represents the HandleClaimSC class that extends org.apache.sling.api.servlets.SlingAllMethodsServlet.  This servlet persists post data that contains special characters to a new node under content/claim.

package com.adobe.aem.sc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.rmi.ServerException;
import java.util.Dictionary;
  

import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

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.SlingSafeMethodsServlet;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.felix.scr.annotations.Reference;
import org.osgi.service.component.ComponentContext;
import javax.jcr.Session;
import javax.jcr.Node; 
import java.util.UUID;
 
import javax.jcr.Repository; 
import javax.jcr.SimpleCredentials; 
import javax.jcr.Node; 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
   
import org.apache.jackrabbit.commons.JcrUtils;
  
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
  
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import javax.jcr.RepositoryException;
import org.apache.felix.scr.annotations.Reference;
import org.apache.jackrabbit.commons.JcrUtils;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
   
 
//Sling Imports
import org.apache.sling.api.resource.ResourceResolverFactory ; 
import org.apache.sling.api.resource.ResourceResolver; 
import org.apache.sling.api.resource.Resource; 
  
/**
 * This Custom Sling Servlet handles special chars posted from Java app
 */


@SlingServlet(paths="/bin/handleclaimSC", methods = "POST", metatype=true)
@Property(name = "sling.auth.requirements", value = "-/bin/handleclaimSC")
public class HandleClaimSC extends org.apache.sling.api.servlets.SlingAllMethodsServlet {
     private static final long serialVersionUID = 2598426539166789515L;
       
     /** Default log. */
     protected final Logger log = LoggerFactory.getLogger(this.getClass());
          
     //Inject a Sling ResourceResolverFactory
     @Reference
     private ResourceResolverFactory resolverFactory;
      
     private Session session;
     
     
     /*
      * Determines if the content/claim node exists 
      * This method returns these values:
      * -1 - if content/claim does not exist
      * 0 - if content/claim node exists; however, contains no children
      * number - the number of children that the content/claim node contains
     */
     private int doesClaimExist(Node content)
     {
    
    	 try
    	 {
    		 int index = 0 ; 
             int childRecs = 0 ; 
              
             java.lang.Iterable<Node> custNode = JcrUtils.getChildNodes(content, "claim");
             Iterator it = custNode.iterator();
             
             
             //only going to be 1 content/claim node if it exists
             if (it.hasNext())
                 {
                 //Count the number of child nodes in content/claim
                 Node claimRoot = content.getNode("claim");
                 Iterable itCust = JcrUtils.getChildNodes(claimRoot); 
                 Iterator childNodeIt = itCust.iterator();
                      
                 //Count the number of claim child nodes 
                 while (childNodeIt.hasNext())
                 {
                     childRecs++;
                     childNodeIt.next();
                 }
                  return childRecs; 
                }
             else
                 return -1; //content/claim does not exist
             
             
             
    	 }
        catch(Exception e)
        {
        	e.printStackTrace(); 
        }
         return 0;
      }    
       
                 
  @Override
  protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServerException, IOException {
	  
	    
	  int num  = 0;
 	 
	    try
	      {
	    	//This servlet handles special chars posted from a Restful client
	    	
	    	  //Get the submitted data that contains special chars	          
	          
	          String id = java.net.URLDecoder.decode(request.getParameter("id"), "UTF-8");
	          String firstName = java.net.URLDecoder.decode(request.getParameter("firstName"),"UTF-8");
	          String lastName = java.net.URLDecoder.decode(request.getParameter("lastName"),"UTF-8");
	          String address = java.net.URLDecoder.decode(request.getParameter("address"),"UTF-8");
	          String cat = java.net.URLDecoder.decode(request.getParameter("cat"),"UTF-8");
	          String state = java.net.URLDecoder.decode(request.getParameter("state"),"UTF-8");
	          String details = java.net.URLDecoder.decode(request.getParameter("details"),"UTF-8");
	          String date = java.net.URLDecoder.decode(request.getParameter("date"),"UTF-8"); 
	          String city = java.net.URLDecoder.decode(request.getParameter("city"),"UTF-8"); 
	           
	           
	          //Persist the Data into the AEM JCR
	          //Invoke the adaptTo method to create a Session 
	          ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null);
	          session = resourceResolver.adaptTo(Session.class);
	                     
	          //Create a node that represents the root node
	          Node root = session.getRootNode(); 
	                           
	          //Get the content node in the JCR
	          Node content = root.getNode("content");
	                            
	          //Determine if the content/claim node exists
	          Node claimRoot = null;
	          
	          
	          int claimRec = doesClaimExist(content);
	          
	           //-1 means that content/claim does not exist
	          if (claimRec == -1)
	        	  //content/claim does not exist -- create it
	        	  claimRoot = content.addNode("claim","nt:unstructured");
	          else
	        	  //content/claim does exist -- retrieve it
	        	  claimRoot = content.getNode("claim");
            
	                 
	          //Store data that contains special chars
	         Node claimNode = claimRoot.addNode("claim"+id +"_"+firstName +"_" +lastName, "nt:unstructured"); 
	                
	         //make sure name of node is unique
	         claimNode.setProperty("id", id); 
	         claimNode.setProperty("firstName", firstName); 
	         claimNode.setProperty("lastName", lastName); 
	         claimNode.setProperty("address", address);  
	         claimNode.setProperty("cat", cat);
	         claimNode.setProperty("state", state);
	         claimNode.setProperty("details", details);
	         claimNode.setProperty("date", date);
	         claimNode.setProperty("city", city);
	                                          
	        log.info("New claim under content/claim"); 
	         
	         // Save the session changes and log out
	        session.save(); 
	        session.logout();
	        
	        //Return claim id
	        response.getWriter().write("claim"+firstName+lastName+id); 
	      }
	             
	       catch(Exception  e){
	           e.printStackTrace(); 
        }
    } 
  }

Modify the Maven POM file 

Modify the POM files to successfully build the OSGi bundle. In the POM file located at C:\AdobeCQ\claimsc\bundle, add the following dependencies.

  • org.apache.felix.scr
  • org.apache.felix.scr.annotations
  • org.apache.jackrabbit
  • org.apache.sling

The following XML represents this POM file.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
    <modelVersion>4.0.0</modelVersion>
    <!-- ====================================================================== -->
    <!-- P A R E N T P R O J E C T D E S C R I P T I O N -->
    <!-- ====================================================================== -->
    <parent>
        <groupId>com.adobe.aem.sc</groupId>
        <artifactId>claimsc</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- ====================================================================== -->
    <!-- P R O J E C T D E S C R I P T I O N -->
    <!-- ====================================================================== -->

    <artifactId>claimsc-bundle</artifactId>
    <packaging>bundle</packaging>
    <name>Claim Special Chars Bundle</name>

    <!-- ====================================================================== -->
    <!-- B U I L D D E F I N I T I O N -->
    <!-- ====================================================================== -->
    <build>

        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-scr-plugin</artifactId>
                <executions>
                    <execution>
                        <id>generate-scr-descriptor</id>
                        <goals>
                            <goal>scr</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>com.adobe.aem.sc.claimsc-bundle</Bundle-SymbolicName>
                    </instructions>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.sling</groupId>
                <artifactId>maven-sling-plugin</artifactId>
                <configuration>
                    <slingUrl>http://${crx.host}:${crx.port}/apps/adobe-training/install</slingUrl>
                    <usePut>true</usePut>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        
         <dependency>
            <groupId>org.apache.sling</groupId>
            <artifactId>org.apache.sling.api</artifactId>
            <version>2.2.4</version>
            <scope>provided</scope>
        </dependency>   
        
        
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.compendium</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.scr.annotations</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
           
        <dependency>
         <groupId>org.apache.felix</groupId>
    
         <artifactId>org.osgi.core</artifactId>
    
         <version>1.4.0</version>
      </dependency>
        
    <dependency>
        <groupId>org.apache.sling</groupId>
        <artifactId>org.apache.sling.commons.osgi</artifactId>
        <version>2.2.0</version>
    </dependency>
               
     
           
    <dependency>
    <groupId>org.apache.jackrabbit</groupId>
    <artifactId>jackrabbit-core</artifactId>
    <version>2.4.3</version>
    </dependency>
        
    <dependency>
    <groupId>org.apache.jackrabbit</groupId>
    <artifactId>jackrabbit-jcr-commons</artifactId>
    <version>2.4.3</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.sling</groupId>
        <artifactId>org.apache.sling.jcr.api</artifactId>
        <version>2.0.4</version>
      </dependency>
 
       <dependency>
        <groupId>org.apache.sling</groupId>
        <artifactId>org.apache.sling.api</artifactId>
        <version>2.0.2-incubator</version>
      </dependency>    
          
      <dependency>
         <groupId>javax.jcr</groupId>
         <artifactId>jcr</artifactId>
         <version>2.0</version>
      </dependency>
 
	<dependency>
    	<groupId>javax.servlet</groupId>
    	<artifactId>servlet-api</artifactId>
    	<version>2.5</version>
	</dependency>
             
    <dependency>
            <groupId>com.day.cq.wcm</groupId>
            <artifactId>cq-wcm-api</artifactId>
            <version>5.5.0</version>
            <scope>provided</scope>
    </dependency>
         
    <dependency>
            <groupId>com.day.cq</groupId>
            <artifactId>cq-commons</artifactId>
            <version>5.5.0</version>
            <scope>provided</scope>
     </dependency>
     
     
     <dependency>
            <groupId>org.apache.sling</groupId>
            <artifactId>org.apache.sling.api</artifactId>
            <version>2.2.4</version>
            <scope>provided</scope>
        </dependency>
         
      <dependency>
         <groupId>javax.jcr</groupId>
         <artifactId>jcr</artifactId>
         <version>2.0</version>
      </dependency>
       
       <dependency>
            <groupId>com.day.cq.wcm</groupId>
            <artifactId>cq-wcm-api</artifactId>
            <version>5.5.0</version>
            <scope>provided</scope>
        </dependency>
         
        <dependency>
            <groupId>com.day.cq</groupId>
            <artifactId>cq-commons</artifactId>
            <version>5.5.0</version>
            <scope>provided</scope>
        </dependency>
               
     
               
    </dependencies>
     
    <repositories>
        <repository>
            <id>adobe</id>
            <name>Adobe Public Repository</name>
            <url>http://repo.adobe.com/nexus/content/groups/public/</url>
            <layout>default</layout>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>adobe</id>
            <name>Adobe Public Repository</name>
            <url>http://repo.adobe.com/nexus/content/groups/public/</url>
            <layout>default</layout>
        </pluginRepository>
    </pluginRepositories>       
      
</project>

Build the OSGi bundle using Maven

Build the OSGi bundle by using Maven. When Maven builds the bundle, it also creates a  serviceComponents.xml file based on the annotations that are included in the com.adobe.aem.sc.HandleClaimSC class. The following XML represents this file.

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
    <scr:component enabled="true" name="com.adobe.aem.sc.SimpleDSComponent">
        <implementation class="com.adobe.aem.sc.SimpleDSComponent"/>
        <service servicefactory="false">
            <provide interface="java.lang.Runnable"/>
        </service>
        <property name="service.pid" value="com.adobe.aem.sc.SimpleDSComponent"/>
    </scr:component>
    <scr:component enabled="true" name="com.adobe.aem.sc.HandleClaimSC">
        <implementation class="com.adobe.aem.sc.HandleClaimSC"/>
        <service servicefactory="false">
            <provide interface="javax.servlet.Servlet"/>
        </service>
        <property name="sling.servlet.paths" value="/bin/handleclaimSC"/>
        <property name="sling.servlet.methods" value="POST"/>
        <property name="sling.auth.requirements" type="String" value="-/bin/handleclaimSC"/>
        <property name="service.pid" value="com.adobe.aem.sc.HandleClaimSC"/>
        <reference name="resolverFactory" interface="org.apache.sling.api.resource.ResourceResolverFactory" cardinality="1..1" policy="static" bind="bindResolverFactory" unbind="unbindResolverFactory"/>
    </scr:component>
</components>

Notice that the implementation class element specifies com.adobe.aem.sc.HandleClaimSC. This lines up with the Java class that extends org.apache.sling.api.servlets.SlingAllMethodsServlet that was created in an earlier step.

To build the OSGi component by using Maven, perform these steps:

  1. Open the command prompt and go to the C:\AdobeCQ\claimsc folder.
  2. Run the following maven command: mvn clean install.
  3. The OSGi component can be found in the following folder: C:\AdobeCQ\claimsc\bundle\target. The file name of the OSGi component is claimsc-bundle-1.0-SNAPSHOT.jar.

Deploy the bundle to Experience Manager

Once you deploy the OSGi bundle, you can post data that contains special characters by using the Java application to the Sling Servlet. After you deploy the OSGi bundle, you can see it in the Apache Felix Web Console.

osgi

Deploy the OSGi bundle that contains the Sling Servlet by performing these steps:

  1. Login to Apache Felix Web Console at http://server:port/system/console/bundles (default admin user = admin with password= admin).
  2. Click the Bundles tab, sort the bundle list by Id, and note the Id of the last bundle.
  3. Click the Install/Update button.
  4. Browse to the bundle JAR file you just built using Maven. (C:\AdobeCQ\claimsc\bundle\target).
  5. Click Install.
  6. Click the Refresh Packages button.
  7. Check the bundle with the highest Id.
  8. Click Active.
  9. Your new bundle should now be listed with the status Active.
  10. If the status is not Active, check the CQ error.log for exceptions. 

After you deploy the OSGi bundle to AEM, you can use the Java client application (created in an earlier step) to post data that contains special characters to AEM. The following illustration shows AEM data located in the JCR that contains special characters.

DataSC

See also

Congratulations, you have just created an AEM sling servlet by using an Adobe Maven Archetype project. Please refer to the AEM community page for other articles that discuss how to build AEM services/applications by using an Adobe Maven Archetype project.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License  Twitter™ and Facebook posts are not covered under the terms of Creative Commons.

Legal Notices   |   Online Privacy Policy