造一個方形的輪子11–后記

造一個方形輪子文章目錄:造一個方形的輪子

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)載請注明出處漓糙!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末铣缠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子昆禽,更是在濱河造成了極大的恐慌蝗蛙,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件醉鳖,死亡現(xiàn)場離奇詭異捡硅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)盗棵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門壮韭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人纹因,你說我怎么就攤上這事喷屋。” “怎么了辐怕?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵逼蒙,是天一觀的道長。 經(jīng)常有香客問我寄疏,道長是牢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任陕截,我火速辦了婚禮驳棱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘农曲。我一直安慰自己社搅,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布乳规。 她就那樣靜靜地躺著形葬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪暮的。 梳的紋絲不亂的頭發(fā)上笙以,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天,我揣著相機(jī)與錄音冻辩,去河邊找鬼猖腕。 笑死拆祈,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的倘感。 我是一名探鬼主播放坏,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼老玛!你這毒婦竟也來了淤年?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤逻炊,失蹤者是張志新(化名)和其女友劉穎互亮,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體余素,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡豹休,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了桨吊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片威根。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖视乐,靈堂內(nèi)的尸體忽然破棺而出洛搀,到底是詐尸還是另有隱情,我是刑警寧澤佑淀,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布留美,位于F島的核電站,受9級特大地震影響伸刃,放射性物質(zhì)發(fā)生泄漏谎砾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一捧颅、第九天 我趴在偏房一處隱蔽的房頂上張望景图。 院中可真熱鬧,春花似錦碉哑、人聲如沸挚币。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妆毕。三九已至,卻和暖如春贮尖,著一層夾襖步出監(jiān)牢的瞬間设塔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工远舅, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留闰蛔,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓图柏,卻偏偏與公主長得像序六,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蚤吹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容