Thursday, 25 July 2013

Uploading files to Adobe Experience Manager DAM using AssetManager API

You can create an Adobe Experience Manager (AEM) application that lets a user select a file from their local desktop and upload it to AEM Digital Asset Manager (DAM). The file is posted to a custom Sling Servlet that persists an image file in the AEM DAM.



An Adobe AEM client web page that lets a user select a file and upload it to AEM

In this example, notice that a file named lake.jpg is selected. Once the file is uploaded, the Sling Servlet persists the file in the AEM DAM, as shown in the following illustration.


A file is located in the Adobe CQ DAM that was uploaded using a Sling Servlet


When you use the AssetManager API to persist a file in the AEM DAM, AEM automatically creates different renditions for the asset, as shown in this illustration.



Java code that works in non-sling Java servlets to upload a file throws an exception within Adobe CQ. That is, using Apache Commons FileUpload application logic (that works in non-sling Java servlets used in other projects) throws this exception:

java.lang.IllegalStateException: Request Data has already been read

Here is an example of Apache Commons FileUpload Java code that works in other projects - but not in Adobe CQ:

 String fileName = "";
         org.apache.commons.fileupload.FileItem fileItem;
         fileName = "";
         fileItem = null;
         Iterator iterator;

         try {
                 
             List items = (new org.apache.commons.fileupload.servlet.ServletFileUpload(new org.apache.commons.fileupload.disk.DiskFileItemFactory())).parseRequest(request);
             iterator = items.iterator();
             while(iterator.hasNext())
             {
                 Object itemObj = iterator.next();
                 org.apache.commons.fileupload.FileItem item = (org.apache.commons.fileupload.FileItem)itemObj;
                 if(item.getFieldName().equals("our-file"))
                 {
                     fileItem = item;
                     fileName = item.getName();

...

At first, I did not realize why code that I have used in other projects would not work in Adobe CQ.  As I researched this issue further, I discovered that Sling reads the file content automatically, so the code attempts to read in the request data twice. 

This explains the exception. Now the question is how do you successfully get the file when using a Sling servlet? The answer is you can read the file using Sling APIs.  The following Java code example represents the doPost method of a sling servlet that reads the file that is uploaded. The fully qualified names of the Java objects are used so you understand the data types used in this code fragment.

 @Override
     protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServerException, IOException {
       
       
    try
    {
    final boolean isMultipart = org.apache.commons.fileupload.servlet.ServletFileUpload.isMultipartContent(request);
    PrintWriter out = null;
     
      out = response.getWriter();
      if (isMultipart) {
        final java.util.Map<String, org.apache.sling.api.request.RequestParameter[]> params = request.getRequestParameterMap();
        for (final java.util.Map.Entry<String, org.apache.sling.api.request.RequestParameter[]> pairs : params.entrySet()) {
          final String k = pairs.getKey();
          final org.apache.sling.api.request.RequestParameter[] pArr = pairs.getValue();
          final org.apache.sling.api.request.RequestParameter param = pArr[0];
          final InputStream stream = param.getInputStream();
          if (param.isFormField()) {
            out.println("Form field " + k + " with value " + org.apache.commons.fileupload.util.Streams.asString(stream) + " detected.");
          } else {
            out.println("File field " + k + " with file name " + param.getFileName() + " detected.");
          }
        }
      }
    }
     
         catch (Exception e) {
             e.printStackTrace();
         }
      
     }

To read this development article, click:

http://helpx.adobe.com/experience-manager/using/uploading-files-aem1.html



Join the Adobe Experience Cloud Community 

Join the Adobe Experience Cloud Community by clicking this banner




I (Scott Macdonald) am a Senior Digital Marketing Community Manager at Adobe Systems with 20 years in the high tech industry. I am also a programmer with knowledge in Java, JavaScript, C#,C++, HTML, XML and ActionScript. If  you would like to see more CQ or other Adobe Digital Marketing end to end articles like this, then leave a comment and let me know what content you would like to see.


TwitterFollow the Digital Marketing Customer Care team on Twitter @AdobeExpCare.

YouTube: Subscribe to the AEM Community Channel


1 comment:

  1. Hi Scott, this is really helpful.

    ReplyDelete