Java 使用 GWT 下载动态文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2822667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Download dynamic file with GWT
提问by Maksim
I have a GWT page where user enter data (start date, end date, etc.), then this data goes to the server via RPC call. On the server I want to generate Excel report with POI and let user save that file on their local machine.
我有一个 GWT 页面,用户在其中输入数据(开始日期、结束日期等),然后这些数据通过 RPC 调用发送到服务器。在服务器上,我想用 POI 生成 Excel 报告,并让用户将该文件保存在他们的本地机器上。
This is my test code to stream file back to the client but for some reason I think it does not know how to stream file to the client when I'm using RPC:
这是我将文件流式传输回客户端的测试代码,但出于某种原因,我认为当我使用 RPC 时,它不知道如何将文件流式传输到客户端:
public class ReportsServiceImpl extends RemoteServiceServlet implements ReportsService {
public String myMethod(String s) {
File f = new File("/excelTestFile.xls");
String filename = f.getName();
int length = 0;
try {
HttpServletResponse resp = getThreadLocalResponse();
ServletOutputStream op = resp.getOutputStream();
ServletContext context = getServletConfig().getServletContext();
resp.setContentType("application/octet-stream");
resp.setContentLength((int) f.length());
resp.setHeader("Content-Disposition", "attachment; filename*=\"utf-8''" + filename + "");
byte[] bbuf = new byte[1024];
DataInputStream in = new DataInputStream(new FileInputStream(f));
while ((in != null) && ((length = in.read(bbuf)) != -1)) {
op.write(bbuf, 0, length);
}
in.close();
op.flush();
op.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
return "Server says: " + filename;
}
}
I've read somewhere on internet that you can't do file stream with RPC and I have to use Servlet for that. Is there any example of how to use Servlet and how to call that servlet from ReportsServiceImpl. Do I really need to make a servlet or it is possible to stream it back with my RPC?
我在互联网上的某个地方读到过,你不能用 RPC 来做文件流,我必须为此使用 Servlet。有没有关于如何使用 Servlet 以及如何从ReportsServiceImpl调用该 servlet 的示例。我真的需要制作一个 servlet 还是可以用我的 RPC 将它流回?
采纳答案by Sripathi Krishnan
You have to make a regular Servlet, you cannotstream binary data from ReportsServiceImpl
. Also, there is no way to call the servlet from ReportsServiceImpl - your client code has to directly invoke the servlet.
您必须创建一个常规的 Servlet,您不能从ReportsServiceImpl
. 此外,无法从 ReportsServiceImpl 调用 servlet - 您的客户端代码必须直接调用 servlet。
On the client side, you'd have to create a normal anchor link with the parameters passed via the query string. Something like <a href="http://myserver.com/myservlet?parm1=value1&.."</a>
.
在客户端,您必须使用通过查询字符串传递的参数创建一个普通的锚链接。类似的东西<a href="http://myserver.com/myservlet?parm1=value1&.."</a>
。
On the server side, move your code to a standard Servlet, one that does NOT inherit from RemoteServiceServlet
. Read the parameters from the request object, create the excel and send it back to the client. The browser will automatically popup the file download dialog box.
在服务器端,将您的代码移动到一个标准的 Servlet,一个不继承自RemoteServiceServlet
. 从请求对象中读取参数,创建 excel 并将其发送回客户端。浏览器会自动弹出文件下载对话框。
回答by Rondo
It's possible to get the binary data you want back through the RPC channel in a number of ways... uuencode, for instance. However, you would still have to get the browser to handle the file as a download.
可以通过多种方式通过 RPC 通道获取您想要的二进制数据......例如 uuencode。但是,您仍然需要让浏览器将文件作为下载进行处理。
And, based on your code, it appears that you are trying to trigger the standard browser mechanism for handling the given mime-type by modifying the response in the server so the browser will recognize it as a download... open a save dialog, for instance. To do that, you need to get the browser to make the request for you and you need the servlet there to handle the request. It can be done with rest urls, but ultimately you will need a serviet to do even that.
而且,根据您的代码,您似乎正在尝试通过修改服务器中的响应来触发处理给定 mime 类型的标准浏览器机制,以便浏览器将其识别为下载...打开保存对话框,例如。为此,您需要让浏览器为您发出请求,并且您需要那里的 servlet 来处理请求。可以使用 rest url 来完成,但最终您将需要一个服务来做到这一点。
You need, in effect, to set a browser window URL to the URL that sends back the modified response object.
实际上,您需要将浏览器窗口 URL 设置为发回修改后的响应对象的 URL。
So this question (about streaming) is not really compatible with the code sample. One or the other (communication protocols or server-modified response object) approach has to be adjusted.
所以这个问题(关于流)与代码示例并不真正兼容。必须调整一种或另一种(通信协议或服务器修改的响应对象)方法。
The easiest one to adjust is the communication method.
最容易调整的是沟通方式。
回答by Italo Borssatto
You can do that just using GWT RPC and Data URIs:
您可以仅使用 GWT RPC 和数据 URI来做到这一点:
- In your example, make your
myMethod
return the file content. - On the client side, format a Data URIwith the file content received.
- Use
Window.open
to open a file save dialog passing the formatted DataURI.
Take a look at this reference, to understand the Data URIusage:
看看这个参考资料,了解数据 URI 的用法: