Java 11手柄不可修复地图

发布于 2025-01-30 16:29:31 字数 1791 浏览 3 评论 0原文

我有一个课程来处理一些上传zpled的文件。 以及一种解压缩和填充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)

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

任何帮助都将受到赞赏

I have a class to process some files which is uploaded zipped.
And a method to unzip and fill a HashMap and convert to an 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();
        }
    }
...
}

When I test with a small example, it works nicely, but when I try with the real case I got this kind of error.

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

I found some hints to deal with it but I don't know exactly what to do.

Any help is appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

春庭雪 2025-02-06 16:29:31

servlet非常烦人。想一想任何给定的servlet可能会运行很多次的概念,并且可能同时多次,因为各种用户都在您的网站上。

它们是两全其美的最糟糕的:Servlet Spec 确保系统为每个请求初始化一个新对象(这意味着,许多不同的请求,有些甚至有些,甚至同时使用,都使用相同的字段),但它 也不能保证相反:系统可以自由这样做。

结论:Servlet中的字段几乎是无用的。但是您有一个,这会引起麻烦:一个“运行”用不可变的掩盖覆盖您的可变哈希图,然后下一个servlet试图在现在不可变的地图中添加东西。

修复程序通常是为了摆脱servlet。如今,有更好的方法可以编写Web应用程序,例如 spark dropwizard

如果您坚持认为,那么您的servlet应该没有任何字段。如果您需要它们,您的servlet代码应该简单地制作一个新对象,然后调用您想要的任何东西 - 您的doget,朋友大多只是form new Mealterhandhandler(req,res) .go()或类似。现在,您实际上有一个实例。

或者,只是..编写代码,以便不需要字段。例如,我不知道为什么在这里需要一个字段。您当前的代码确实如此;

  • 接收请求并解析内容(您没有粘贴此部分)
  • 代码显然调用processzipfile,该什么也没返回,但使用字段传达了数据。 (这在servlets中不起作用)。
  • 然后,您的请求处理代码然后将该字段用于内容。

似乎很容易替换它 - 没有字段,拥有processzipfile方法返回该映射。

servlets are quite annoying. Think of the notion that any given servlet is likely going to run many times, and probably many times simultaneously, as various users hit your site.

They are the worst of both worlds: The servlet spec does not guarantee that the system initializes a new object for every request (meaning, it is possible that many different requests, some even simultaneous, are all using the same fields), but it als does not guarantee the opposite either: The system is free to do so.

Conclusion: Fields in servlets are pretty much useless. But you have one, and it's causing troubles: One 'run' overwrites your mutable hashmap with an immutable one, and then the next servlet tries to add stuff to this now immutable map.

The fix is generally to just get rid of servlets. There are better ways to write web apps these days, such as spark, DropWizard, Spring, and many others.

If you insist, then your servlets should not have any fields. If you desire them, your servlet code should simply make a new object and then invoke whatever you want there - your doGet and friends are mostly just oneliners of the form new ActualHandler(req, res).go() or similar. Now you actually have one instance per request.

Or, just.. write the code so that no fields are needed. I don't see why you need a field here, for example. Your current code does;

  • Receive the request and parse stuff out (you didn't paste this part)
  • That code evidently invokes processZipFile which returns nothing, but conveys data back using a field. (This does not work in servlets).
  • Your request handling code then uses that field for stuff.

Seems easy to replace that - don't have a field, have the processZipFile method return that map instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文