日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

为什么不应该重写 service 方法?

發(fā)布時(shí)間:2025/3/21 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么不应该重写 service 方法? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

故事通常是這樣開始的:
從前,有一個(gè)程序猿,他語重心長(zhǎng)地對(duì)孫子說:“孩子,要是你以后寫servlet,最好不要重寫service方法啊”
孫子大為不解,程序猿又說:“聽爺爺?shù)?#xff0c;準(zhǔn)沒錯(cuò),爺爺?shù)臓敔斁褪沁@么說的……”

——為什么不應(yīng)該重寫service方法呢?

如果你也曾思考過這個(gè)問題,但暫時(shí)無解,這篇文章或許可以給你一點(diǎn)啟發(fā)。

先來看一個(gè)具體的例子:

當(dāng)時(shí)我正在osc看紅薯的一篇大作,只見我右手F12熟練的打開了chrome的開發(fā)者工具,左手迅猛的按了幾下F5,然后看到了這個(gè)結(jié)果。

聰明的你一定已經(jīng)發(fā)現(xiàn),除了第一個(gè)名為12_77118的請(qǐng)求返回狀態(tài)為200,其他的都為304,那么200和304有什么區(qū)別呢?這個(gè)稍后解釋。

一切從代碼里面來,我們先拋開理論,看一個(gè)具體的code:

我編寫了一個(gè)index.html,如下:

<html> <body> <h3>I'm?a?test?page?.?</h3> <h3>I'm?a?test?page?.?</h3> <h3>I'm?a?test?page?.?</h3> <h3>I'm?a?test?page?.?</h3> <h3>I'm?a?test?page?.?</h3> <h3>I'm?a?test?page?.?</h3> <h3>I'm?a?test?page?.?</h3> </body> </html>

我們來訪問這個(gè)頁(yè)面看看。

Image(2)

這是我第一次訪問這個(gè)頁(yè)面(表示本地并沒有對(duì)這個(gè)文件的緩存):

我們來看看http請(qǐng)求和響應(yīng)的消息頭:

《圖:一》

為了作為對(duì)比,我們?cè)貴5刷新一次:

《圖:二》

這次請(qǐng)求的頭信息中多了一條If-Modified-Since,而且返回的響應(yīng)中,狀態(tài)變?yōu)榱?04,這是怎么回事?還記得紅薯那篇文章頁(yè)中的304么,你會(huì)發(fā)現(xiàn),304多出現(xiàn)在對(duì)于靜態(tài)資源的請(qǐng)求上面。

原來對(duì)于靜態(tài)資源來說:

  • 當(dāng)瀏覽器第一次發(fā)起請(qǐng)求時(shí)(請(qǐng)求頭中沒有If-Modified-Since),server會(huì)在響應(yīng)中告訴瀏覽器這個(gè)資源最后修改的時(shí)間(響應(yīng)頭中的Last-Modified)。(見圖一)

  • 瀏覽器也很聰明,當(dāng)你再次(點(diǎn)擊鏈接,或者F5,或者回車,但是不能是ctrl+F5)請(qǐng)求這個(gè)資源時(shí),瀏覽器會(huì)詢問server這個(gè)資源自上次告訴我的最后修改時(shí)間以來有沒有被修改(請(qǐng)求頭中If-Modified-Since)。(見圖二)

  • 如果資源沒有被修改,server返回304狀態(tài)碼,并不會(huì)再次將資源發(fā)送給瀏覽器,瀏覽器則很知趣的使用本地的緩存文件。(見圖二)

  • 所以所有的靜態(tài)資源如果沒有發(fā)生變化,通常是不會(huì)傳遞多次的,不管什么瀏覽器或者server都應(yīng)該遵守這種詢問的約定。看起來很爽啊,很智能是不是?這種約定的機(jī)制就是?http緩存協(xié)商——這是約定優(yōu)于配置的又一體現(xiàn)。

    有了緩存協(xié)商的知識(shí),理解為什么我們不應(yīng)該重寫service就很容易了。還是從代碼出發(fā),這次我們看一個(gè)復(fù)雜一點(diǎn)的例子:

    在這個(gè)例子中,我們請(qǐng)求一個(gè)控制器(MeServlet),然后轉(zhuǎn)向一個(gè)視圖(index.html),為了簡(jiǎn)單起見,web.xml中將只有這個(gè)servlet的配置:

    <web-app><servlet><servlet-name>me</servlet-name><servlet-class>com.me.web.MeServlet</servlet-class></servlet><servlet-mapping><servlet-name>me</servlet-name><url-pattern>/test</url-pattern></servlet-mapping> </web-app>

    然后是MeServlet:

    public?class?MeServlet?extends?HttpServlet?{@Overrideprotected?void?service(HttpServletRequest?req,?HttpServletResponse?res)throws?ServletException,?IOException?{/***?1.?處理具體的業(yè)務(wù):*?--?處理請(qǐng)求參數(shù)*?--?檢查緩存*?--?處理具體數(shù)據(jù)*?--?更新緩存*/doBizLogic(req,?res);/***?2.?根據(jù)處理的結(jié)果轉(zhuǎn)向具體的視圖:*?--?這里假設(shè)就是?index.html*/getServletContext().getRequestDispatcher("/index.html").include(req,?res);}public?void?doBizLogic(HttpServletRequest?request,?HttpServletResponse?response)?{System.out.println("do?biz.");} }

    可以看到,每次F5刷新返回的狀態(tài)碼都是200,讓我們看看具體的請(qǐng)求和響應(yīng)頭:

    我們發(fā)現(xiàn)無論我們?nèi)绾嗡⑿马?yè)面,每次響應(yīng)狀態(tài)都是200,index.html的內(nèi)容每次都被完整的發(fā)送給瀏覽器,這看起來很笨,為什么不像靜態(tài)資源一樣進(jìn)行緩存協(xié)商呢?原因是緩存協(xié)商是基于http請(qǐng)求和響應(yīng)頭中的Modified信息的,如果沒有這個(gè)信息,是無法進(jìn)行緩存協(xié)商的。而對(duì)于動(dòng)態(tài)內(nèi)容而言,server無法幫我們決定內(nèi)容是不是有改變,也無法替我們決定動(dòng)態(tài)內(nèi)容的最后修改時(shí)間。

    所以它不會(huì)幫我們?cè)陧憫?yīng)中加上Last-Modified,我們必須自己來做這件事,我們小小地修改一下MeServlet:

    public?class?MeServlet?extends?HttpServlet?{@Overrideprotected?long?getLastModified(HttpServletRequest?req)?{/***?這里你要自己決定動(dòng)態(tài)內(nèi)容的最后修改時(shí)間,例如你可以返回*?--?數(shù)據(jù)緩存最后更新的時(shí)間*?--?簡(jiǎn)單起見,我們假設(shè)最后的修改時(shí)間是?1000*/return?1000;}@Overrideprotected?void?service(HttpServletRequest?req,?HttpServletResponse?res)throws?ServletException,?IOException?{/***?1.?處理具體的業(yè)務(wù):*?--?處理請(qǐng)求參數(shù)*?--?檢查緩存*?--?處理具體數(shù)據(jù)*?--?更新緩存*/doBizLogic(req,?res);/***?2.?根據(jù)處理的結(jié)果轉(zhuǎn)向具體的視圖:*?--?這里假設(shè)就是?index.html*/getServletContext().getRequestDispatcher("/index.html").include(req,?res);}public?void?doBizLogic(HttpServletRequest?request,?HttpServletResponse?response)?{System.out.println("do?biz.");} }

    你會(huì)看到getLastModified這個(gè)方法是重寫的,說明HttpServlet中已經(jīng)有了這個(gè)方法,我們使用這個(gè)方法來告訴server在這個(gè)動(dòng)態(tài)資源中,最后內(nèi)容變化的時(shí)間是多少。最理想的情況是server會(huì)自己回調(diào)這個(gè)方法,那就太省心啦。

    我們先訪問的看看:發(fā)現(xiàn)依然每次都是200,server沒有告訴瀏覽器最后的修改時(shí)間,緩存協(xié)商機(jī)制無法工作。

    先別沮喪,忘了我們要解釋什么問題嗎——為什么不要重寫service方法。也許你已經(jīng)猜到了,如果你看看service方法的實(shí)現(xiàn),現(xiàn)在你已經(jīng)明白了,service方法自己實(shí)現(xiàn)了緩存協(xié)商的機(jī)制,如果我們重寫它,反而將這中良好的機(jī)制給去掉了。

    我們?cè)傩薷囊幌?#xff0c;這次我們重寫doGet,在doGet中完成完全相同的邏輯:

    public?class?MeServlet?extends?HttpServlet?{@Overrideprotected?long?getLastModified(HttpServletRequest?req)?{/***?這里你要自己決定動(dòng)態(tài)內(nèi)容的最后修改時(shí)間,例如你可以返回*?--?數(shù)據(jù)緩存最后更新的時(shí)間*?--?簡(jiǎn)單起見,我們假設(shè)最后的修改時(shí)間是?1000*/return?1000;}@Overrideprotected?void?doGet(HttpServletRequest?req,?HttpServletResponse?res)throws?ServletException,?IOException?{/***?1.?處理具體的業(yè)務(wù):*?--?處理請(qǐng)求參數(shù)*?--?檢查緩存*?--?處理具體數(shù)據(jù)*?--?更新緩存*/doBizLogic(req,?res);/***?2.?根據(jù)處理的結(jié)果轉(zhuǎn)向具體的視圖:*?--?這里假設(shè)就是?index.html*/getServletContext().getRequestDispatcher("/index.html").include(req,?res);}public?void?doBizLogic(HttpServletRequest?request,?HttpServletResponse?response)?{System.out.println("do?biz.");} }

    這次在訪問,

    終于出現(xiàn)了久違的Last-Modified,再次回車請(qǐng)求頁(yè)面,哈哈變成304了。

    現(xiàn)在你也許已經(jīng)清楚了,為什么不應(yīng)該重寫service方法,似乎是為了保留HttpServlet默認(rèn)實(shí)現(xiàn)的緩存協(xié)商的機(jī)制;其實(shí)還有另外一個(gè)原因:就是禁用你沒有在servlet中重寫的方法,例如post、head等,這樣就從一定程度上提高了安全性。

    理論到此為止,現(xiàn)在讓我們來看看緩存協(xié)商機(jī)制有什么實(shí)際的好處:

    還是紅薯的那邊文章,我們現(xiàn)在全加載(ctrl+F5)一次看看,

    我們看到總共發(fā)起了45個(gè)請(qǐng)求,請(qǐng)求的數(shù)據(jù)量為198.93KB,然后F5刷新一次:

    這次只有36個(gè)請(qǐng)求,數(shù)據(jù)量只有23.62KB

    我們看到這篇文章被9960個(gè)id訪問, 而每一個(gè)id實(shí)際上可能訪問這個(gè)頁(yè)面多次(像我這樣,實(shí)際的數(shù)據(jù)可能得問問紅薯),然后我們看到很多304靜態(tài)資源都是整站通用的:

    如果你是osc的常客,并且不經(jīng)常更換瀏覽器,不經(jīng)常清理緩存,甚至其他人的頭像都可以是通用的,為了簡(jiǎn)單起見,我們這里考慮每個(gè)id都只訪問這個(gè)頁(yè)面一次,并且假設(shè)所有的資源都已經(jīng)緩存在用戶本地,得出:

    (198.93-23.62)×9960 = 1746086.6KB = 1705.1637M = 1.665G。

    很驚人吧,這只是一個(gè)頁(yè)面,別忘了,我們還假設(shè)所有的用戶都只訪問一次,你想想osc上面有多少篇博文,加起來……

    流量是什么,是銀子啊。

    幸運(yùn)的是,這些省銀子的事情瀏覽器和server都已經(jīng)幫我們做好了,那我們就不需要關(guān)心這個(gè)了嗎??我們看到12_77118這個(gè)請(qǐng)求所占用的資源也不少,如果文章再長(zhǎng)點(diǎn),再長(zhǎng)點(diǎn)的話……還會(huì)更大。

    如果紅薯愿意,也可以讓這個(gè)請(qǐng)求實(shí)現(xiàn)緩存協(xié)商,可以進(jìn)一步減少流量。

    當(dāng)然這里的計(jì)算并不是完全的精確,實(shí)際的情況復(fù)雜很多,但是這個(gè)計(jì)算的量級(jí)應(yīng)該是對(duì)的,是值得參考的。

    流量涉及的另一個(gè)問題就是帶寬,以更小的貸款提供更高的并發(fā)是每個(gè)站長(zhǎng)應(yīng)該追求的。不過考慮到osc以新聞為主,一次性消費(fèi),所以……不過那時(shí)題外話了。

    好了,如果你有耐心看到這里,我想你也許會(huì)對(duì)service有了新的理解,為什么我們不應(yīng)該重寫這個(gè)方法。

    萬事有例外,如果你需要實(shí)現(xiàn)一個(gè)前端控制器的話,就是另外一回事了,這留給大家自己思考。

    總結(jié)

    以上是生活随笔為你收集整理的为什么不应该重写 service 方法?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 性xxx18| 中文字幕一区二区人妻痴汉电车 | 日韩精品色哟哟 | 口舌奴vk | 超碰在线免费观看97 | 天天碰免费视频 | 欧美sm视频 | 丰满人妻一区二区三区免费视频 | 91免费视频 | 午夜精品久久久久久久久 | 日韩视频久久 | 国产在线专区 | 特黄做受又粗又大又硬老头 | 明里柚番号 | 日日操日日摸 | 精品久久五月天 | 欧美三级又粗又硬 | 亚洲爽片| 欧美三级午夜理伦三级 | 国精品一区二区三区 | 韩日av片 | 亚洲视频精品在线 | 国产精品扒开腿做爽爽爽a片唱戏 | 亚洲第一区在线播放 | 日韩在线视频二区 | 欧美第二页 | 中文字幕久久久久久久 | 亚洲情在线| 免费日本视频 | 日韩乱码在线观看 | 在线看片网址 | 亚洲午夜无码久久久久 | 香蕉av777xxx色综合一区 | 日韩成人av在线 | a毛片在线| 国产黄色网| 成人a级免费视频 | 欧美另类第一页 | 精品国产无码一区二区三区 | 欧美丰满熟妇xxxxx | 天码人妻一区二区三区在线看 | 无套内谢的新婚少妇国语播放 | 97公开免费视频 | 正在播放木下凛凛xv99 | 国产av一区二区三区最新精品 | 欧亚毛片 | 日本黄色激情视频 | 国产伊人精品 | 亚洲美女色 | 日韩国产精品一区二区 | 欧美aa视频 | 爱情岛论坛亚洲线路一 | 大屁股白浆一区二区三区 | 蜜臀久久99精品久久一区二区 | 日韩中文视频 | 亚洲精品aⅴ中文字幕乱码 国产精品调教视频 | 国产乱淫av公| 国产日批视频在线观看 | 神马午夜51 | 五月天婷婷综合 | 国产精品h | 国产精品久久久久久久久久妞妞 | 青青草亚洲 | 欧美极品一区二区三区 | 91九色论坛| 在线视频网| 香蕉视频在线看 | 亚洲天堂社区 | 天堂精品视频 | 色欧美片视频在线观看 | 嫩草大剧院 | 久久亚洲精品石原莉奈 | 亚洲黄色影院 | а中文在线天堂 | 国产亚洲精品久久久久久无几年桃 | 精品一区二区在线免费观看 | 黄色不雅视频 | 久久三级精品 | 超碰xxx| 亚洲最大的成人网 | 在线观看免费高清在线观看 | 人妻一区二区三区免费 | 亚洲精品五月 | 欧美裸体xxxx | 老头把女人躁得呻吟 | 免费毛片在线播放免费 | 午夜888 | 亚洲精品一区二区三区在线 | 天堂新版8中文在线8 | 又大又硬又爽免费视频 | 精品一区二区久久久 | 高h视频在线播放 | 四虎最新站名点击进入 | 免费人成网站 | 欧美呦交 | 欧美日韩精品一区二区三区蜜桃 | 欧美成人不卡 | 欧美日韩在线播放三区四区 | 欧美用舌头去添高潮 |