Java 11句柄不可修改的地图
Java 11 handle unmodifiable map
我有一个 class 来处理一些上传的压缩文件。
以及一种解压缩并填充 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 中的字段几乎没有用。但是你有一个,它造成了麻烦:一个 'run' 用一个不可变的 hashmap 覆盖了你的可变 hashmap,然后下一个 servlet 试图向这个现在不可变的 map 添加东西。
解决方法通常是删除 servlet。现在有更好的方法来编写 Web 应用程序,例如 spark, DropWizard, Spring 和许多其他方法。
如果您坚持,那么您的 servlet 不应该有任何字段。如果你需要它们,你的 servlet 代码应该简单地创建一个新对象,然后在那里调用你想要的任何东西——你的 doGet
和朋友大多只是 new ActualHandler(req, res).go()
或类似形式的单行者。现在每个请求实际上有一个实例。
或者,只是.. 编写代码以便不需要任何字段。例如,我不明白你为什么需要一个字段。您当前的代码可以;
- 接收请求并解析内容(你没有粘贴这部分)
- 该代码显然调用了
processZipFile
,但 return 什么都没有,而是使用字段传回数据。 (这在 servlet 中不起作用)。
- 您的请求处理代码然后使用该字段作为内容。
似乎很容易替换它 - 没有字段,使用 processZipFile
方法 return 映射。
我有一个 class 来处理一些上传的压缩文件。
以及一种解压缩并填充 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 中的字段几乎没有用。但是你有一个,它造成了麻烦:一个 'run' 用一个不可变的 hashmap 覆盖了你的可变 hashmap,然后下一个 servlet 试图向这个现在不可变的 map 添加东西。
解决方法通常是删除 servlet。现在有更好的方法来编写 Web 应用程序,例如 spark, DropWizard, Spring 和许多其他方法。
如果您坚持,那么您的 servlet 不应该有任何字段。如果你需要它们,你的 servlet 代码应该简单地创建一个新对象,然后在那里调用你想要的任何东西——你的 doGet
和朋友大多只是 new ActualHandler(req, res).go()
或类似形式的单行者。现在每个请求实际上有一个实例。
或者,只是.. 编写代码以便不需要任何字段。例如,我不明白你为什么需要一个字段。您当前的代码可以;
- 接收请求并解析内容(你没有粘贴这部分)
- 该代码显然调用了
processZipFile
,但 return 什么都没有,而是使用字段传回数据。 (这在 servlet 中不起作用)。 - 您的请求处理代码然后使用该字段作为内容。
似乎很容易替换它 - 没有字段,使用 processZipFile
方法 return 映射。