簡體   English   中英

Java 11句柄不可修改 map

[英]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)

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

任何幫助表示贊賞

servlets 很煩人。 想一想任何給定的 servlet 可能會運行很多次,並且可能會同時運行很多次,因為各種用戶訪問您的站點。

它們是兩個世界中最糟糕的:servlet 規范保證系統為每個請求初始化一個新的 object(意思是,有可能許多不同的請求,有些甚至是同時的,都使用相同的字段),但它也也不保證相反的情況:系統可以自由地這樣做。

結論: servlets 中的字段幾乎沒有用 但是你有一個,它造成了麻煩:一個“運行”用一個不可變的覆蓋了你的可變 hashmap,然后下一個 servlet 試圖向這個現在不可變的 map 添加東西。

修復通常只是擺脫 servlets。現在有更好的方法來編寫 web 應用程序,例如sparkDropWizardSpring等等。

如果你堅持,那么你的 servlets 應該沒有任何字段。 如果你需要它們,你的 servlet 代碼應該簡單地創建一個新的 object 然后調用你想要的任何東西 - 你的doGet和朋友大多只是new ActualHandler(req, res).go()或類似形式的單行代碼。 現在每個請求實際上有一個實例。

或者,只是.. 編寫代碼以便不需要任何字段。 例如,我不明白你為什么需要一個字段。 您當前的代碼可以;

  • 接收請求並解析內容(你沒有粘貼這部分)
  • 該代碼顯然調用processZipFile ,它不返回任何內容,但使用字段傳回數據。 (這在 servlet 中不起作用)。
  • 然后您的請求處理代碼使用該字段作為內容。

替換它似乎很容易 - 沒有字段,讓processZipFile方法返回map。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM