gpt4 book ai didi

java - 在多个独立的 post 请求期间使 Servlet 中的对象保持 Activity 状态

转载 作者:行者123 更新时间:2023-12-01 13:42:47 27 4
gpt4 key购买 nike

我目前正在构建一个 Web 应用程序,使用 Tomcat 7 中的 Java Servlet。该网络应用程序使用 Jupload 作为客户端小程序,以提供更舒适的方式将多个文件上传到服务器。然而,目前这个小程序每个 post 请求都会发送一个文件。我实现的 Servlet 从输入流读取数据并将其存储在本地。很好,这有效。但另外我必须将文件名和路径等存储在数据库中。这就是为什么我想将这些信息存储在一个对象中并将它们保存在一个列表中,并在来自小程序的传入请求期间收集这些信息。该列表当前被实现为类变量。

public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private ArrayList<ImageUploadInformation> uploadInfos; //I know, thats bad.


public UploadServlet() {
super();
uploadInfos = new ArrayList<>();
}


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// not relevant stuff...
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//accessing data stream directly
//jUpload sends file information and file binary data in one stream, so we have to deal with mixed data in streams
InputStream inputStream = request.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);

//some other stuff, not relevant

byte[] b = IOUtils.toByteArray(inputStream);
File file = null;
if (finalFilename != null) {
file = new File(finalFilename);
}
if (file != null) {
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(b);
bos.close();
fos.close();
}
else
throw new IOException("File Creation on Server failed!");

//adding Meta informations about file in list
uploadInfos.add(new ImageUploadInformation(filename, relativeDir,"1"));
}
}

但是我在这里的一些线程上读到,在线程安全的情况下,这确实是一件坏事。我在编写 Web 应用程序方面不太有经验,所以也许下面的方法是完全错误的。我尝试将列表绑定(bind)为请求的 session 属性。

 request.getSession().setAttribute("uploadInfos", uploadInfos);

但是,我无法使用它,因为它是来自小程序的全新发布请求,这就是为什么我无法在另一个请求中访问此列表。我读到了一些关于在 ServletContext 中绑定(bind)对象的内容,但我认为这也是一个不好的做法,但我找不到任何证据。我怎样才能实现,我可以通过多个独立请求存储此列表。如果所有文件仅在一个 post 请求中发送到 servlet,我可以在 doPost() 方法内部创建列表,那会更好吗?认为这可以在 Jupload 中配置,但实际上文件可能非常大。在一个请求中发送大量文件是常见做法吗?感谢您提供任何帮助以及有关此类内容的其他文献的链接。

@edit:额外的东西也尝试过这个..

        if (request.getSession().getAttribute("uploadInfos") != null) {     
uploadInfos = (ArrayList<ImageUploadInformation>)request.getSession().getAttribute("uploadInfos");
uploadInfos.add(new ImageUploadInformation(filename, relativeDir,"1"));
System.out.println("UploadInfos found in Session, current size: " +uploadInfos.size());
request.getSession().setAttribute("uploadInfos", uploadInfos);
}
else {
System.out.println("No UploadInfos found, creating new List...");
uploadInfos = new ArrayList<>();
uploadInfos.add(new ImageUploadInformation(filename, relativeDir,"1"));
request.getSession().setAttribute("uploadInfos", uploadInfos);
}

这是测试的输出:

Incoming post request
No UploadInfos found, creating new List...
Incoming post request
No UploadInfos found, creating new List...
Incoming post request
No UploadInfos found, creating new List...

最佳答案

你就快到了。 session 是在服务器上存储您希望跨请求保留的状态的位置。

Servlet 可以从多个线程和不同的客户端调用;容器还可以根据需要创建或销毁实例,因此 servlet 本身不应该保存状态。需要删除“uploadInfos”字段。该列表应该是线程安全的集合,例如CopyOnWriteArrayList,并存储在 session 中。首先从session中获取属性,如果为null,则创建一个新列表并将其存储在session中。然后像以前一样将您的条目添加到列表中。

还值得一提的是,在服务器上的请求之间存储状态有时是不可取的,因为它会使系统更难以横向扩展。另一种方法是使用 JavaScript 将状态存储在客户端上。不过,就你而言,我不会为此烦恼,只需将其存储在 session 中即可。更容易。

关于java - 在多个独立的 post 请求期间使 Servlet 中的对象保持 Activity 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20574737/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com