从android

时间:2015-04-23 13:33:19

标签: java android download android-download-manager

我尝试使用Android手机上的浏览器从我的网络应用程序下载文件(在我的情况下,我使用spring mvc但是尽管如此,因为我认为它是一个常见的问题,而不是特定于框架的)。事情是在Android设备中尝试使用chrome或本机浏览器,文件下载永远不会结束,总是显示In progressqueue(取决于Android版本,我尝试使用4.1.1和5.1.1)下载应用。

我尝试使用内联或附件更改所涉及的典型http-headersContent-TypeContent-Disposition,指定Content-Length但没有运气。

问题是,对于Windows或Linux中的桌面浏览器,文件在每种情况下都能正确下载。

我的一些尝试:

  1. 使用org.springframework.http.ResponseEntity

    @RequestMapping(value= {"/evidenciaDownload"},method = RequestMethod.GET)
    public ResponseEntity<byte[]> getEvidencia(
            @RequestParam(value = "paramsCoded", required = true) String paramsCoded) throws IOException {
    
        String url = configPropsService.getEvidenciaUrlDownload() + URLEncoder.encode(paramsCoded,"UTF-8");
        logger.info("[getEvidencia] Recuperem l'evidencia de : " + url);
    
        // bytes are correct
        byte[] evidencia = downloadFile(url);
    
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/pdf");
        //responseHeaders.set("Content-Disposition","attachment; filename=\"evidencia.pdf\";");
        responseHeaders.set("Content-Disposition","inline; filename=evidencia.pdf");
        responseHeaders.setContentLength(evidencia.length);
        return new ResponseEntity<byte[]>(evidencia, responseHeaders,HttpStatus.CREATED);
    }
    
  2. 直接使用org.springframework.web.bind.annotation.ResponseBodybytes[]上返回文档produces = "application/pdf"@RequestMapping

    @RequestMapping(value= {"/evidenciaDownload"},method = RequestMethod.GET, produces = "application/pdf")
    public @ResponseBody byte[] getEvidencia(
            @RequestParam(value = "paramsCoded", required = true) String paramsCoded) throws IOException {
    
        String url = configPropsService.getEvidenciaUrlDownload() + URLEncoder.encode(paramsCoded,"UTF-8");
        logger.info("[getEvidencia] Recuperem l'evidencia de : " + url);
    
        return downloadFile(url);
    
    }
    
  3. 或者在javax.servlet.http.HttpServletResponse输出流中写入文件并指定标题:

    @RequestMapping(value= {"/documentDownload"},method = RequestMethod.GET)
    public void getDocument(
            @RequestParam(value = "paramsCoded", required = true) String paramsCoded, 
            HttpServletResponse response) throws IOException {
    
        String url = configPropsService.getDocumentsNotficacioUrlDownload() + URLEncoder.encode(paramsCoded,"UTF-8");       
        logger.info("[getDocument] Recuperem el document de : " + url);
    
        // bytes are correct
        byte[] downloadFile = downloadFile(url);
    
        ServletOutputStream outputStream = response.getOutputStream();
    
        int fileLength = IOUtils.copy(new ByteArrayInputStream(downloadFile), outputStream);
        response.setHeader("Content-Disposition","attachment;filename=\"evidencia.pdf\"");
        response.setContentLength(fileLength);
        response.setContentType("application/pdf");
        outputStream.flush();
        outputStream.close();
    }
    
  4. 就像我说的那样,3个案例在windows / linux上的桌面浏览器上运行良好,但不适用于Chrome设备和原生浏览器。

1 个答案:

答案 0 :(得分:1)

我发布了答案,因为我花了一些时间找到问题的原因,我希望这可以帮助某人。

问题最终是由部署我的Web应用程序的服务器证书引起的,问题是我的服务器证书是由预生产证书颁发机构颁发的,该机构具有使用弱算法(md5)散列的中间证书链。此外,它的CA来自预生产,所以它不受机器人的信任。

在桌面文件中,文件正确下载,因为在下载之前我跳过了警告服务器证书问题的页面。

问题是在android上,至少使用chrome,关于服务器证书的警告页面也会出现,我跳过它,但是在下载管理器中,文件无限期地出现在队列中或正在进行中,但没有错误消息。我花了一些时间来解决这个问题,因为我没有任何关于正在发生的事情的错误信息或指示。

最后,我更改了我的服务器证书,并使用了由受信任的CA颁发的正确证书,并且文件开始正确下载,以解决问题中指定的三种代码方法。