Java 11处理不可修改的映射



我有一个类来处理一些上传的压缩文件。以及解压缩和填充HashMap并转换为Collection.unmodifiableMap的方法。

public class MyClass extends HttpServlet {
...
private Map<String, String> rnaseqfiles = new HashMap<>();
...
private void processZipFile(String zipfile) throws Exception {
String fileName = zipfile;
byte[] buffer = new byte[1024];
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(fileName))) {
ZipEntry zipEntry = zis.getNextEntry();

while (zipEntry != null) {
File newFile = new File(diretorio, zipEntry.toString());
if (zipEntry.isDirectory()) {
if (!newFile.isDirectory() && !newFile.mkdirs()) {
throw new IOException("Failed to create directory " + newFile);
}
} else {
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
rnaseqfiles.put(zipEntry.toString(), newFile.getAbsolutePath());
}
zipEntry = zis.getNextEntry();
}

rnaseqfiles = Collections.unmodifiableMap(rnaseqfiles);

zis.closeEntry();
zis.close();
}
}
...
}

当我用一个小例子测试时,它工作得很好,但是当我用实际情况进行测试时,我得到了这种错误。

java.lang.UnsupportedOperationException
at java.base/java.util.Collections$UnmodifiableMap.put(Collections.java:1457)

我找到了一些处理它的提示,但我不知道该怎么做。

感谢您的帮助

servlet非常烦人。考虑这样一个概念:当不同的用户访问您的站点时,任何给定的servlet都可能会运行多次,并且可能同时运行多次。

它们是两个世界中最糟糕的:servlet规范没有保证系统为每个请求初始化一个新对象(意思是,可能有许多不同的请求,有些甚至是同时的,都使用相同的字段),但是它也

结论:servlet中的字段几乎是无用的。但是你有一个,它引起了麻烦:一个"运行"用一个不可变的hashmap覆盖你的可变hashmap,然后下一个servlet试图向这个不可变的map添加东西。

解决方法通常是摆脱servlet。现在有更好的方法来编写web应用程序,比如spark, DropWizard, Spring等等。

如果您坚持,那么您的servlet不应该有任何字段。如果您需要它们,您的servlet代码应该简单地创建一个新对象,然后调用您想要的任何对象—您的doGet和朋友通常只是new ActualHandler(req, res).go()或类似形式的联机程序。现在每个请求实际上有一个实例。

,或者只是. .编写代码时不需要任何字段。例如,我不明白为什么这里需要一个字段。

  • 接收请求并解析内容(您没有粘贴此部分)
  • 这段代码显然调用了processZipFile,它没有返回任何东西,而是使用一个字段返回数据。(这在servlet中不起作用)。
  • 您的请求处理代码然后使用该字段的内容。

似乎很容易取代-不需要字段,有processZipFile方法返回映射代替。

最新更新