Android WebView加载Liferay Portlet时PDF下载无响应问题求助
嘿,我之前也在Android WebView里处理过Liferay Portlet的PDF下载问题,刚好踩过类似的坑,给你几个实用的解决方案:
核心问题:WebView默认不处理下载请求
WebView本身不会自动触发文件下载操作,哪怕服务器正确返回了PDF响应,也需要我们手动拦截并处理下载逻辑。
方案一:给WebView设置DownloadListener(最常用)
这是处理WebView下载的标准方式,通过拦截下载请求,调用系统的DownloadManager来完成文件保存:
1. 初始化WebView时添加下载监听
在你的WebView初始化代码里加入这段逻辑:webView.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) { // 构建下载请求 DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setMimeType(mimeType); // 解析服务器返回的文件名(从Content-Disposition头中提取) String filename = URLUtil.guessFileName(url, contentDisposition, mimeType); // 关键:传递Cookie,因为Liferay Portlet需要用户会话验证 request.addRequestHeader("Cookie", CookieManager.getInstance().getCookie(url)); // 设置下载提示和通知 request.setDescription("正在下载PDF文件"); request.setTitle(filename); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // 指定下载到系统下载目录 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); // 发起下载 DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); if (downloadManager != null) { downloadManager.enqueue(request); Toast.makeText(getApplicationContext(), "开始下载", Toast.LENGTH_SHORT).show(); } } });这里一定要注意传递Cookie,否则Liferay服务器会因为没有会话信息拒绝你的下载请求,毕竟Portlet通常需要用户登录才能访问。
2. 检查Liferay的响应头格式
你当前的响应头设置基本没问题,但建议给文件名加上双引号,避免特殊字符导致解析失败:res.addProperty(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + cod + ".pdf\"");另外确保
Content-Length也正确返回,这样系统能显示准确的下载进度。3. 处理Android权限问题
如果你的应用目标是Android 6.0(API 23)及以上,需要动态申请WRITE_EXTERNAL_STORAGE权限(如果下载到外部存储的话),否则会保存失败。可以在触发下载前先检查权限:if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1001); } else { // 这里执行下载逻辑,或者在权限申请通过后重新触发 }记得在
onRequestPermissionsResult回调中处理权限通过后的下载操作。
方案二:处理AJAX发起的下载请求
如果你的Portlet是通过AJAX请求生成PDF的(比如前端JS调用ResourceURL),WebView的DownloadListener可能拦截不到请求。这时候可以:
- 在Liferay端生成PDF后,返回一个重定向到PDF文件的URL,让WebView自动触发下载;
- 或者在前端JS中,当收到PDF的Blob数据时,创建一个隐藏的
<a>标签来触发下载:
这种方式需要前端和Liferay后端配合,确保能正确传递Blob数据和文件名。function handlePdfDownload(blobData, fileName) { const downloadUrl = window.URL.createObjectURL(blobData); const link = document.createElement('a'); link.href = downloadUrl; link.download = fileName; document.body.appendChild(link); link.click(); window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(link); }
内容的提问来源于stack exchange,提问作者fipries
相关产品推荐
相关产品推荐

