一種解決SpringBoot無法讀取js/css靜態資源的新方法
阿新 • • 發佈:2019-05-07
忽略 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靜態資源的新方法