经过长时间的等待发送文件给客户端
我有一个Java Servlet,使一些报告。当用户选择一个报告时,它会对数据库进行查询并将xls报告传输到客户端。全部采用同步方式。问题是,有时我有很多记录要从数据库中获取,我想提供更好的用户体验,允许用户在报告正在处理时做其他事情,并以某种方式弹出过程完成。有没有一个Java库或一些技术来避免长时间等待并实现该目标?经过长时间的等待发送文件给客户端
现在我准备了一段代码,以异步方式完成报告并发送一封电子邮件给已注册的客户端,使用来自下载文件的url,但必须用其他内容替换它,因为我不能再通过电子邮件进行沟通。
在此先感谢
也许你可以在后台使用java线程?
一个多线程的客户端服务器程序来下载我的图像文件。 由于有四个文件要下载,客户端会进行4次连接尝试。这并不限于4,但FileServer发送的文件将在第四次尝试后重复。保存对话框和文件保存在不同的线程中完成,以免妨碍文件下载。
这里是文件服务器...
public class FileServer {
private final ExecutorService exec = Executors.newCachedThreadPool();
final String[] fileNames = {
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 1.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 2.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 3.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 4.jpg"
};
public void start() throws IOException {
ServerSocket socket = new ServerSocket(7777);
System.out.println("Waiting for client message...");
while (!exec.isShutdown()) {
try {
for (final String fileName : fileNames){
final Socket conn = socket.accept();
exec.execute(new Runnable() {
public void run() {
sendFile(conn,fileName);
}
});
}
} catch (RejectedExecutionException e) {
if (!exec.isShutdown())
log("task submission rejected", e);
}
}
}
public void stop() {
System.out.println("Shutting down server...");
exec.shutdown();
}
private void log(String msg, Exception e) {
Logger.getAnonymousLogger().log(Level.WARNING, msg, e);
}
public void sendFile(Socket conn, String fileName) {
File myFile = new File(fileName);
if (!myFile.exists()) {
log("File does not exist!",null);
}
// file does exist
System.out.println(Thread.currentThread().getName());
System.out.println("AbsolutePath:" + myFile.getAbsolutePath());
System.out.println("length: " + myFile.length());
if (myFile.exists()) {
try {
ObjectOutputStream oos = new ObjectOutputStream(
conn.getOutputStream());
oos.writeObject(myFile);
oos.close();
} catch (IOException e) {
log("IOException Error", e);
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
FileServer fs = new FileServer();
fs.start();
}
}
这里是FileServerClient ...
public class FileServerClient {
private final ExecutorService exec = Executors.newCachedThreadPool();
Frame myFrame = new Frame();
List<File> fileList = new ArrayList<File>();
public void receiveFileFromServer() throws Exception{
Socket sock = null;
InputStream socketInputStream = null;
String host = "localhost";
int port = 7777;
for (int i=0;i<4;i++) {
sock = new Socket(host, port);
socketInputStream = sock.getInputStream();
System.out.println("Connection successful...");
// recieve the file
ObjectInputStream ois = new ObjectInputStream(socketInputStream);
// file from server is deserialized
final File myfile = (File) ois.readObject();
fileList.add(myfile);
// deserialized file properties
System.out.println("AbsolutePath: " + myfile.getAbsolutePath());
System.out.println("FileName:" + myfile.getName());
System.out.println("length" + myfile.length());
exec.execute(new Runnable() {
public void run() {
saveFile(myfile);
}
});
}
}
private void saveFile(File myfile) {
FileDialog fileDialog = new FileDialog(myFrame,
"Choose Destination for "+ myfile.getName(), FileDialog.SAVE);
fileDialog.setDirectory(null);
fileDialog.setFile("enter file name here");
fileDialog.setVisible(true);
String targetFileName = fileDialog.getDirectory()
+ fileDialog.getFile() + ".jpg";
System.out.println("File will be saved to: " + targetFileName);
copyBytes(myfile, targetFileName);
}
private void copyBytes(File originalFile, String targetFileName) {
try {
FileInputStream in = new FileInputStream(originalFile);
FileOutputStream out = new FileOutputStream(targetFileName);
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
out.close();
in.close();
} catch (Exception e) {
log("IOException Error", e);
}
}
private void log(String msg, Exception e) {
Logger.getAnonymousLogger().log(Level.WARNING, msg, e);
}
public static void main(String[] args) throws Exception {
FileServerClient client = new FileServerClient();
client.receiveFileFromServer();
}
}
继承人我拿到这个,我不知道一个库,将完全匹配您的需要,你可能需要一些自定义的开发。
- 我相信你已经实现了异步服务,完成后发送 出一封电子邮件通知。让 线程更新某种作业表 - 一个db表 或某个应用程序/会话范围映射中的条目,而不是发送电子邮件。
- 有一个servlet/restful ws
- 在某个网址显示该工作表。以常规的 间隔轮询网址。 Ajax轮询是js库中的标准功能JQuery, Prototype。
- 当您收到某个报告完成的回复时,显示 某些弹出式窗口,或者可能是您在客户端上的某个类别的事件 。
我在这里还没有考虑认证/授权问题,你也需要照顾。
希望这有助于
您可以从客户端发出异步请求。让我们假设你的客户端是一个html页面。当用户选择一个报告并点击'提交'时,你可以用报告参数(jQuery对此有用)来触发ajax请求。最好在用户主页上保留一段说明“准备好的报告”的部分。然后客户可以到准备好的报告部分下载报告。如上述注释中所述,您可能还必须实施弹出窗口,通知用户所请求的报告已准备就绪。当ajax请求成功返回时弹出窗口显示。但是,客户端可能在报告完成时已注销,因此在用户登录时,可以在“准备报告”部分中再次使用下载链接,这可能是个好主意。
只需使用多个线程,每个进程都有一个线程。 – OmniOwl