April 13, 2020
Estimated Post Reading Time ~

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

}



By aem4beginner

1 comment:

  1. hi, nicce post, can i ask u question im really new to AEM, im using js where am i supposed to put this code? is it on js-use file? and will it work, im using aem 6.5 now

    ReplyDelete

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