1. 程式人生 > >一種解決SpringBoot無法讀取js/css靜態資源的新方法

一種解決SpringBoot無法讀取js/css靜態資源的新方法

忽略 tro while res 容易 靜態 hashmap hfile !=

作為依賴使用的SpringBoot工程很容易出現自身靜態資源被主工程忽略的情況。但是作為依賴而存在的Controller方法卻不會失效,我們知道,Spring MVC對於靜態資源的處理也不外乎是路徑匹配,讀取資源封裝到Response中響應給瀏覽器,所以,解決的途徑就是自己寫一個讀取Classpath下靜態文件並響應給客戶端的方法。

對於ClassPath下文件的讀取,最容易出現的就是IDE運行ok,打成jar包就無法訪問了,該問題的原因還是在於getResources()不如getResourceAsStream()方法靠譜。

本就是SpringBoot的問題場景,何不用Spring現成的ClassPathResource類呢?

ReadClasspathFile.java

public class ReadClasspathFile {
    public static String read(String classPath) throws IOException {
        ClassPathResource resource = new ClassPathResource(classPath);
        BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(),"UTF-8"));
        StringBuilder builder = new StringBuilder();
        String line;
        while ((line = reader.readLine())!=null){
            builder.append(line+"\n");
        }
        return builder.toString();
    }
}

接下來就是Controller層進行映射匹配響應了,這裏利用Spring MVC取個巧,代碼如下:

    @ResponseBody
    @RequestMapping(value = "view/{path}.html",produces = {"text/html; charset=UTF-8"})
    public String view_html(@PathVariable String path) throws IOException {
        return ReadClasspathFile.read("view/"+path+".html");
    }

    @ResponseBody
    @RequestMapping(value = "view/{path}.js",produces = {"application/x-javascript; charset=UTF-8"})
    public String view_js(@PathVariable String path) throws IOException {
        return ReadClasspathFile.read("view/"+path+".js");
    }

通過後戳(html、js)進行判斷,以應對不同的Content-Type類型,靜態資源的位置也顯而易見,位於resources/view下。

最後就是使用緩存進行優化了,如果不加緩存,那麽每次請求都涉及IO操作,開銷也比較大。關於緩存的設計,這裏使用WeakHashMap,代碼如下:

public class ReadClasspathFile {
    
    private static WeakHashMap<String,String> map = new WeakHashMap<>();
    
    public static String read(String classPath) throws IOException {
        String s = map.get(classPath);
        if (s!=null){
            return s;
        }
        ClassPathResource resource = new ClassPathResource(classPath);
        BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(),"UTF-8"));
        StringBuilder builder = new StringBuilder();
        String line;
        while ((line = reader.readLine())!=null){
            builder.append(line+"\n");
        }
        //DCL雙檢查鎖
        if (!map.containsKey(classPath)){
            synchronized (ReadClasspathFile.class){
                if (!map.containsKey(classPath)){
                    map.put(classPath,builder.toString());
                }
            }
        }
        return builder.toString();
    }
}

一種解決SpringBoot無法讀取js/css靜態資源的新方法