Expand my Community achievements bar.

SOLVED

Servlet code to download dam images

Avatar

Level 7

Using the below code it downloads the image but when I open that image it is corrupted. 
Please help me find a way to resolve this issue

 

 

 

(
    service = Servlet.class,
    property = { SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
        SLING_SERVLET_PATHS + "=/bin/assetdownloader"})
public class AssetDownloader extends SlingAllMethodsServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    AssetDownloadService assetDownloadService;

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

            Resource assetResource = resourceResolver.getResource(request.getParameter("download"));

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

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

 

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @Ronnie09,

I am not sure if using AssetDownloadService is needed in your case - you are not using the result returned by assetDownload method anyway.

I have made some changes in your code, and it looks to work correct. So sending request like /bin/assetdownloader?download=/content/dam/we-retail-screens/usa.png - image should be automatically downloaded and there should not be any issue to open it after download from local.

 

@Component(service = Servlet.class, property = {
        SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
        SLING_SERVLET_PATHS + "=/bin/assetdownloader" })
public class AssetDownloader extends SlingSafeMethodsServlet {

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

            Resource assetResource = resourceResolver.getResource(request.getParameter("download"));
            Asset asset = assetResource.adaptTo(Asset.class);

            response.setContentType(asset.getMimeType());
            response.setHeader("Content-Disposition", "attachment; filename=" + asset.getName());
            response.setStatus(HttpServletResponse.SC_OK);

            try (InputStream is = asset.getOriginal().getStream()) {
                IOUtils.copy(is, response.getOutputStream());
            } catch (IOException e) {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

View solution in original post

2 Replies

Avatar

Correct answer by
Community Advisor

Hi @Ronnie09,

I am not sure if using AssetDownloadService is needed in your case - you are not using the result returned by assetDownload method anyway.

I have made some changes in your code, and it looks to work correct. So sending request like /bin/assetdownloader?download=/content/dam/we-retail-screens/usa.png - image should be automatically downloaded and there should not be any issue to open it after download from local.

 

@Component(service = Servlet.class, property = {
        SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
        SLING_SERVLET_PATHS + "=/bin/assetdownloader" })
public class AssetDownloader extends SlingSafeMethodsServlet {

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

            Resource assetResource = resourceResolver.getResource(request.getParameter("download"));
            Asset asset = assetResource.adaptTo(Asset.class);

            response.setContentType(asset.getMimeType());
            response.setHeader("Content-Disposition", "attachment; filename=" + asset.getName());
            response.setStatus(HttpServletResponse.SC_OK);

            try (InputStream is = asset.getOriginal().getStream()) {
                IOUtils.copy(is, response.getOutputStream());
            } catch (IOException e) {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

Avatar

Community Advisor

If you are on AEM as a cloud service consider redirecting the request to the original or desired rendition using a filter, rather than streaming the binary.