我尝试使用Android手机上的浏览器从我的网络应用程序下载文件(在我的情况下,我使用spring mvc但是尽管如此,因为我认为它是一个常见的问题,而不是特定于框架的)。事情是在Android设备中尝试使用chrome或本机浏览器,文件下载永远不会结束,总是显示In progress
或queue
(取决于Android版本,我尝试使用4.1.1和5.1.1)下载应用。
我尝试使用内联或附件更改所涉及的典型http-headers
:Content-Type
,Content-Disposition
,指定Content-Length
但没有运气。
问题是,对于Windows或Linux中的桌面浏览器,文件在每种情况下都能正确下载。
我的一些尝试:
使用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);
}
直接使用org.springframework.web.bind.annotation.ResponseBody
在bytes[]
上返回文档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);
}
或者在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();
}
就像我说的那样,3个案例在windows / linux上的桌面浏览器上运行良好,但不适用于Chrome设备和原生浏览器。
答案 0 :(得分:1)
我发布了答案,因为我花了一些时间找到问题的原因,我希望这可以帮助某人。
问题最终是由部署我的Web应用程序的服务器证书引起的,问题是我的服务器证书是由预生产证书颁发机构颁发的,该机构具有使用弱算法(md5)散列的中间证书链。此外,它的CA来自预生产,所以它不受机器人的信任。
在桌面文件中,文件正确下载,因为在下载之前我跳过了警告服务器证书问题的页面。
问题是在android上,至少使用chrome,关于服务器证书的警告页面也会出现,我跳过它,但是在下载管理器中,文件无限期地出现在队列中或正在进行中,但没有错误消息。我花了一些时间来解决这个问题,因为我没有任何关于正在发生的事情的错误信息或指示。
最后,我更改了我的服务器证书,并使用了由受信任的CA颁发的正确证书,并且文件开始正确下载,以解决问题中指定的三种代码方法。