2015-04-23 207 views
0

我想从我的web应用程序使用浏览器在Android手机上下载文件(在我的情况下,我使用弹簧mvc尽管在这,因为我认为这是一个常见的问题,而不是框架特定)。事情是,尝试在Android设备的铬或本地浏览器的文件下载永远不会结束,总是出现在下载应用程序In progressqueue(取决于Android版本,我尝试与4.1.1和5.1.1)。从Android的HTTPS在浏览器中下载文件

我试图改变参与http-headersContent-Type,Content-Disposition与内联或附件,指定Content-Length没有运气。

事情是,在Windows或Linux的桌面浏览器的文件下载正确的情况下。

我的一些尝试:在@RequestMapping

@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); 
} 
  • 直接使用org.springframework.web.bind.annotation.ResponseBody返回文档bytes[]produces = "application/pdf"

    1. 使用org.springframework.http.ResponseEntity

      @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); 
      
      } 
      
    2. 或写在javax.servlet.http.HttpServletResponse OutputStream的文件,并指定标题:

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

    的事情是,我说3例在Windows/Linux上的桌面浏览器中运行良好,惟未对铬和原生浏览器android设备。

  • 回答

    1

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

    问题最终是由我的web应用程序部署的服务器证书引起的,问题在于我的服务器证书是由具有中间证书链的预生产证书颁发机构颁发的,该证书链使用弱算法(md5)散列。另外它的CA来自前期制作,因此它不被android所信任。

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

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

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