造一個方形輪子文章目錄:造一個方形的輪子
01兜辞、解決遺留問題
最后的最后迎瞧,來解決一下靜態(tài)文件的問題吧,這個問題在9里提出來的逸吵,但做的時候才發(fā)現(xiàn)其實從加進(jìn)來DisplayServlet進(jìn)來開始就已經(jīng)出問題了凶硅,只是我一直沒有用到,所以沒發(fā)現(xiàn)扫皱,具體的問題是因為我把DisplayServlet綁定到了"/"路徑上足绅,導(dǎo)致所以的請求都被DisplayServlet接收了捷绑,包括靜態(tài)文件,然后按它的邏輯跑一遍肯定是找不到對應(yīng)的Controller的编检,最后就返回了404胎食。
解決問題的梳理:
1、指定tomcat的webapp目錄為靜態(tài)資源目錄
2允懂、使用DefaultServlet處理靜態(tài)資源
3厕怜、打包后(靜態(tài)資源在jar包里)處理靜態(tài)資源訪問問題
4、分別驗證開發(fā)階段及打包運行階段靜態(tài)資源/接口是否可用
指定不用靜態(tài)目錄重新設(shè)置一下就可以蕾总,之前一直使用的是隨機(jī)生成的臨時目錄粥航,而且還沒有刪除,時間長了會有很多垃圾目錄生百,看了SpringBoot的源碼递雀,原來文件還可以在JVM銷毀的時候刪除,果然Java里還有很多可以學(xué)習(xí)的地方蚀浆,直接上代碼:
ClassesPathUtil.java:
public class ClassesPathUtil {
private static final Logger log = LoggerFactory.getLogger(ClassesPathUtil.class);
/**
* 項目目錄(.../classes)
*/
private String projectPath;
/**
* 靜態(tài)資源目錄(.../classes/public)
*/
private String publicPath;
public ClassesPathUtil(Class clzz){
String basePath = clzz.getResource("").getPath();
log.info("basePath+++++{}", basePath);
// ..../classes
if(basePath.indexOf("classes")>0) {
projectPath = basePath.substring(0, basePath.indexOf("classes")+7);
publicPath = basePath.substring(0, basePath.indexOf("target"));
publicPath = publicPath+"target/classes/public";
} else {
projectPath = basePath.substring(0, basePath.indexOf("!")+1);
publicPath = SquareApplication.TEMP_TOMCAT_DIR;
}
}
}
主要改了設(shè)置publicPath目錄的地方缀程,因為開發(fā)階段設(shè)置的是編譯后的public目錄,而打包運行的時候直接指定臨時目錄市俊,哪jar包里的靜態(tài)資源如何訪問嗎杨凑?接著往下看:
SquareApplication.java:
public class SquareApplication {
//....
private static String SUFFIXS = "htm,html,css,js,jpg,jpeg,png,gif,json,mp4,mp3,avi,rm";
public static String TEMP_TOMCAT_DIR = "/tmp/square/tomcat";
public static void run(Class clzz, String[] args) {
try {
//...
tomcat = new Tomcat();
tomcat.setPort(TOMCAT_PORT);
// 設(shè)置Tomcat工作目錄
File f = new File(TEMP_TOMCAT_DIR);
if(!f.exists()){
f.mkdirs();
}
f.deleteOnExit();
tomcat.setBaseDir(f.getPath());
Context context = tomcat.addWebapp(CONTEXT_PATH, classesPathUtil.getPublicPath());
// jar包中靜態(tài)文件特殊處理
if(classesPathUtil.getProjectPath().indexOf("!")>0) {
String jar = "jar:"+classesPathUtil.getProjectPath()+"/";
URL url = new URL(jar);
context.setResources(new StandardRoot(context));
context.getResources().createWebResourceSet(WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/", url, "/public");
}
// 添加DsipatcherServlet
Wrapper wrapper = Tomcat.addServlet(context, "DispatcherServlet", new DispatcherServlet());
wrapper.addMapping("/");
// 設(shè)置靜態(tài)資源走默認(rèn)Servlet處理
Tomcat.addServlet(context, "DefaultServlet", new DefaultServlet());
String[] suffixs = SUFFIXS.split(",");
for (String suffix : suffixs) {
context.addServletMappingDecoded("*."+suffix, "DefaultServlet");
}
// 執(zhí)行這句才能支持JDNI查找
tomcat.enableNaming();
tomcat.getConnector().setURIEncoding(ENCODING);
tomcat.start();
log.info("Tomcat started on port(s): {} with context path '{}'", TOMCAT_PORT, CONTEXT_PATH);
log.info("Started Application in {} ms." , (System.currentTimeMillis() - startTime));
// 保持服務(wù)器進(jìn)程
tomcat.getServer().await();
} catch (Exception e) {
if(e instanceof SquareException){
log.error(((SquareException) e).getMsg());
}
log.error("Application startup failed...", e);
}
}
}
代碼都有注釋邏輯不復(fù)雜,Tomcat目錄設(shè)置還是使用臨時目錄摆昧,同時調(diào)用File的deleteOnExit()方法使目錄在JVM銷毀時刪除臨時目錄
然后是設(shè)置webapp目錄撩满,根據(jù)上邊的ClassesPathUtil代碼可知,如果是開發(fā)階段那么設(shè)置的是*classes/public目錄绅你,如果是打完jar包運行的話設(shè)置的是臨時目錄
再下邊是判斷如果當(dāng)前在jar包中運行則將jar包的靜態(tài)資源添加到容器的WebResource中伺帘,以達(dá)到在訪問jar包中靜態(tài)資源的目的
最后將默認(rèn)的DefaultServlet注冊到容器中,同時設(shè)置需要DefaultServlet處理的靜態(tài)資源后綴忌锯,這樣就解決了我們上邊提出的問題
測試效果(square-demo項目):
訪問靜態(tài)資源:
瀏覽器請求:http://localhost:8765/square-demo/square.html
返回頁面:success!!!
訪問接口:
瀏覽器請求:http://localhost:8765/square-demo/id?id=1
返回頁面:success! name is : ixx
02伪嫁、后記
從六月份開始第一篇到現(xiàn)在已經(jīng)過去了三個月了,從更新頻率上能看的出來后邊明顯更新變慢了汉规,多種原因吧礼殊,總算是完成了這個系列,雖然有很多的不足针史,以后如果有機(jī)會再做修改吧,至少寫這個的最初上的我達(dá)到了碟狞,讓自己多思考每天用的輪子到底是怎么轉(zhuǎn)的啄枕。
雖說叫方形的輪子可寫完才覺得真的這玩意連別說方形了,連輪子都算不上族沃,一個能稱為輪子的框架真的有太多需要考慮的點了频祝,而且每一個點都值得深入研究學(xué)習(xí)一下泌参,這也是后邊做業(yè)務(wù)之余要去學(xué)習(xí)的一個方向吧。
03常空、遺留問題
有人看嗎 = =沽一!
本篇代碼地址: https://github.com/iuv/square/tree/square11
演示項目地址: https://github.com/iuv/square-demo
本文作者: ixx
本文鏈接: http://jianpage.com/2019/09/20/square11
版權(quán)聲明: 本作品采用 知識共享署名-非商業(yè)性使用-相同方式共享 4.0 國際許可協(xié)議 進(jìn)行許可。轉(zhuǎn)載請注明出處漓糙!