使用 liferay ServeResource 下载文件到浏览器
Download a file to browser with liferay ServeResource
TL;DR 如何使用 java portlet ResourceRequest 从我的服务器下载文件?
我正在使用 GenericPortlet class 使用 Liferay 6.1.0 portlet 为我们的 CMS 构建本质上是一个浏览器。在 view.jsp 中,一旦用户打开了 CMS 资源,并且如果资源(HTML 页面)有指向 PDF 或图像的链接,这些链接将触发以下代码以请求下载资源(模仿正常行为):
view.jsp
<portlet:resourceURL var="ajaxResourceUrl"/>
$("#file-viewer").on("click", "a", function(e){
/* Prevent normal link navigation behavior*/
e.preventDefault();
/* Get the name of the file we want to download*/
var linkPath = $(this).attr("href");
/* Send the path to the server with resource request*/
$.ajax({
method: 'POST',
url: '<%= ajaxResourceUrl %>',
data: {"action": "displayAttachment", "attachment": linkPath },
dataType: "text",
success: function(data) {
console.log("success:" + data.substring(0, 10));
if(data !== ""){
if(linkPath.substring(linkPath.length - 4, linkPath.length) === ".pdf"){
/* Resource is a PDF */
} else {
/* Resource is HTML */
var html = data;
var uri = "data:text/html," + encodeURIComponent(html);
var newWindow = window.open(uri);
}
} else {
$("#file-viewer").html("Error retrieving attachment \n" + $("#file-viewer").html());
}
},
error: function(err) {
console.log("error" + err);
}
});
});
在服务器上通过此方法处理:
CMSBrowser.java
public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException {
String action = request.getParameter("action");
// handler for multiple ajax actions
if (new String("displayItem").equals(action)) {
//other irrelevant code
} else if (new String("displayAttachment").equals(action)) {
String filePath = request.getParameter("attachment");
PortletPreferences portletPreferences = request.getPreferences();
String rootPath = portletPreferences.getValue("rootPath", "");
filePath = rootPath + filePath;
try {
File f = new File(filePath);
System.out.println("Trying to serve: " + filePath);
String mimeType = request.getPortletSession().getPortletContext().getMimeType(f.getName());
response.setContentType(mimeType);
response.addProperty(
HttpHeaders.CACHE_CONTROL, "max-age=3600, must-revalidate");
OutputStream out = response.getPortletOutputStream();
InputStream in = new FileInputStream(f); // some InputStream
byte[] buffer = new byte[4096];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.flush();
in.close();
out.close();
} catch (IOException e) {
_log.error("serveResource: Unable to write IO stream, IOException: ", e);
}
}
}
我在 Eclipse、浏览器或服务器日志中没有收到任何错误。除了 ajax 成功方法 returns 和 "Error retrieving attachment" 之外没有任何反应,以防服务器没有返回任何内容。
我根据第 4 post 找到了 java 代码 here。
具体来说,我正在尝试将此用于 download/open 在服务器上但不在 portlet/portal 或网络上可访问的新选项卡中的 PDF 和图像。此方法适用于 HTML 个页面。
我的问题是如何使用 java portlet ResourceRequest 从我的服务器下载文件?
(如果右括号或大括号不匹配,请忽略这一点,我不得不在此处删除大量代码 post;所有内容都在我的 [=54 中正确排列和关闭=]).
经过多次尝试类似的解决方案后,我尝试删除 view.jsp 中的 AJAX 函数并将其替换为:
window.open('<%= ajaxResourceUrl %>&action=displayAttachment&attachment=' + linkPath);
这(不知何故)奏效了,现在它允许我在新选项卡中打开 HTML、PDF 和图像。
TL;DR 如何使用 java portlet ResourceRequest 从我的服务器下载文件?
我正在使用 GenericPortlet class 使用 Liferay 6.1.0 portlet 为我们的 CMS 构建本质上是一个浏览器。在 view.jsp 中,一旦用户打开了 CMS 资源,并且如果资源(HTML 页面)有指向 PDF 或图像的链接,这些链接将触发以下代码以请求下载资源(模仿正常行为):
view.jsp
<portlet:resourceURL var="ajaxResourceUrl"/>
$("#file-viewer").on("click", "a", function(e){
/* Prevent normal link navigation behavior*/
e.preventDefault();
/* Get the name of the file we want to download*/
var linkPath = $(this).attr("href");
/* Send the path to the server with resource request*/
$.ajax({
method: 'POST',
url: '<%= ajaxResourceUrl %>',
data: {"action": "displayAttachment", "attachment": linkPath },
dataType: "text",
success: function(data) {
console.log("success:" + data.substring(0, 10));
if(data !== ""){
if(linkPath.substring(linkPath.length - 4, linkPath.length) === ".pdf"){
/* Resource is a PDF */
} else {
/* Resource is HTML */
var html = data;
var uri = "data:text/html," + encodeURIComponent(html);
var newWindow = window.open(uri);
}
} else {
$("#file-viewer").html("Error retrieving attachment \n" + $("#file-viewer").html());
}
},
error: function(err) {
console.log("error" + err);
}
});
});
在服务器上通过此方法处理:
CMSBrowser.java
public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException {
String action = request.getParameter("action");
// handler for multiple ajax actions
if (new String("displayItem").equals(action)) {
//other irrelevant code
} else if (new String("displayAttachment").equals(action)) {
String filePath = request.getParameter("attachment");
PortletPreferences portletPreferences = request.getPreferences();
String rootPath = portletPreferences.getValue("rootPath", "");
filePath = rootPath + filePath;
try {
File f = new File(filePath);
System.out.println("Trying to serve: " + filePath);
String mimeType = request.getPortletSession().getPortletContext().getMimeType(f.getName());
response.setContentType(mimeType);
response.addProperty(
HttpHeaders.CACHE_CONTROL, "max-age=3600, must-revalidate");
OutputStream out = response.getPortletOutputStream();
InputStream in = new FileInputStream(f); // some InputStream
byte[] buffer = new byte[4096];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.flush();
in.close();
out.close();
} catch (IOException e) {
_log.error("serveResource: Unable to write IO stream, IOException: ", e);
}
}
}
我在 Eclipse、浏览器或服务器日志中没有收到任何错误。除了 ajax 成功方法 returns 和 "Error retrieving attachment" 之外没有任何反应,以防服务器没有返回任何内容。
我根据第 4 post 找到了 java 代码 here。
具体来说,我正在尝试将此用于 download/open 在服务器上但不在 portlet/portal 或网络上可访问的新选项卡中的 PDF 和图像。此方法适用于 HTML 个页面。
我的问题是如何使用 java portlet ResourceRequest 从我的服务器下载文件?
(如果右括号或大括号不匹配,请忽略这一点,我不得不在此处删除大量代码 post;所有内容都在我的 [=54 中正确排列和关闭=]).
经过多次尝试类似的解决方案后,我尝试删除 view.jsp 中的 AJAX 函数并将其替换为:
window.open('<%= ajaxResourceUrl %>&action=displayAttachment&attachment=' + linkPath);
这(不知何故)奏效了,现在它允许我在新选项卡中打开 HTML、PDF 和图像。