Expand my Community achievements bar.

How to download AEM Assets Programitically ?

Avatar

Level 2

Hi everyone,

I am new to AEM Assets and I am just trying to download AEM Asset using AssetDownlaodService. The problem here is that the method for downloadAsset is returning me a empty value to the servlet. I am unable to find out the reason behind this. Any suggestion or idea will be Appreciatable.

 

Below is the code which i am writing for downloading the asset :

 

import com.day.cq.dam.api.jobs.AssetDownloadService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletPaths;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.jcr.Node;
import javax.jcr.Session;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.*;
import java.util.HashSet;
import java.util.Set;

@Component(service = Servlet.class)
@SlingServletPaths(value = "/bin/assetdownloader")
public class AssetDownloader extends SlingAllMethodsServlet {

@Reference
AssetDownloadService assetDownloadService;

@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {

try {

ResourceResolver resourceResolver = request.getResourceResolver();
Session session = resourceResolver.adaptTo(Session.class);

Resource assetResource = resourceResolver.getResource("/content/dam/we-retail/en/features/cart.png/jcr:content");

Resource assetDataResource = resourceResolver.getResource("/content/dam/we-retail/en/features/cart.png/jcr:content/renditions/original/jcr:content");

Node assetNode = assetDataResource.adaptTo(Node.class);
InputStream inputStream = assetNode.getProperty("jcr:data").getBinary().getStream();

OutputStream outputStream = new ByteArrayOutputStream();
IOUtils.copy(inputStream, outputStream);

Set<Resource> assetSet = new HashSet<>();
assetSet.add(assetResource);
assetSet.add(assetDataResource);

String damAsset = assetDownloadService.assetDownload(assetResource, assetSet, true, false, false, StringUtils.EMPTY, null, "Downloadasset.zip", StringUtils.EMPTY, outputStream);

session.save();
response.setContentType("text/html");
if (StringUtils.equals(damAsset, StringUtils.EMPTY)){
response.getWriter().write("Nothing To Download :(");
} else {
response.getWriter().write("AEM Asset to Download : " + damAsset);
}

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


}
}


Thanks in advance

7 Replies

Avatar

Employee Advisor

Hi @RameshKumar306 

Welcome to Adobe Community !!
I am not a JAVA coding expert, I can share the AssetDownloadService API documentation for Adobe AEM

https://www.adobe.io/experience-manager/reference-materials/6-5/javadoc/com/day/cq/dam/api/jobs/Asse...

This might help.

Thanks,

Vikram Gaur

Avatar

Community Advisor

Hi @RameshKumar306  Can you Asset download Servlet configuration, whether it is enabled or disabled. 

Follow below documentation to enable it if it is not..

 

https://experienceleague.adobe.com/docs/experience-manager-cloud-service/content/assets/manage/downl...

Avatar

Level 2

Hey @Nitin_laad,

I checked my configurations, AssetDownloadServlet is enabled.

Thanks

Avatar

Community Advisor

Hi @RameshKumar306, I did some quick changes, simplifications, and it looks it is working, I am able to download asset which path is hardcoded in servlet. There are still some minor issues - but main case is working.

import com.day.cq.dam.api.jobs.AssetDownloadService;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletPaths;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.*;
import java.util.HashSet;
import java.util.Set;

@Component(service = Servlet.class)
@SlingServletPaths(value = "/bin/assetdownloader")
public class AssetDownloader extends SlingAllMethodsServlet {

    @Reference
    AssetDownloadService assetDownloadService;

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        try {
            ResourceResolver resourceResolver = request.getResourceResolver();

            Resource assetResource = resourceResolver.getResource("/content/dam/we-retail/en/features/cart.png");

            Set<Resource> assetSet = new HashSet<>();
            assetSet.add(assetResource);

            String damAsset = assetDownloadService.assetDownload(assetResource, assetSet, true, false, false, null, null, "Downloadasset.zip", StringUtils.EMPTY, response.getOutputStream());
            response.setContentType("application/zip");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Avatar

Level 2

Hey @lukasz-m ,
Thanks, The servlet is working now. But only the issue is that it shows the binary data of the asset on the servlet response screen it is not downloading to my local system. Please suggest something for this as well and you were talking about some minor issues, please tell me about those too.

Thanks again 

Avatar

Community Advisor

@RameshKumar306, I've made some changes in my implementation, mainly adding missing headers that should allow to handle download request correctly. Regarding the minor issues, it was actually the fact you already mentioned, that instead of download browser shows the binary data - but this was not the case for all the browser. Anyway this should be solved in below implementation.

import com.day.cq.dam.api.jobs.AssetDownloadService;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletPaths;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.*;
import java.util.HashSet;
import java.util.Set;

@Component(service = Servlet.class)
@SlingServletPaths(value = "/bin/assetdownloader")
public class AssetDownloader extends SlingAllMethodsServlet {

    @Reference
    AssetDownloadService assetDownloadService;

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        try {
            ResourceResolver resourceResolver = request.getResourceResolver();

            Resource assetResource = resourceResolver.getResource("/content/dam/we-retail/en/features/cart.png");

            Set<Resource> assetSet = new HashSet<>();
            assetSet.add(assetResource);

            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment; filename=Downloadasset.zip");
            assetDownloadService.assetDownload(assetResource, assetSet, true, false, false, null, null, "Downloadasset.zip", StringUtils.EMPTY, response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Avatar

Community Advisor

if i use this to download for folders within aem dam asset folder  say /content/dam/we-retail/en/people ,  the downloaded zip file when extracted has one extra folder with file name. How to get ride of those extra folders?