放棄 JSP 吧,讓自己的路走的寬一些。。。
前段時間,我和一位群友因為要不要學(xué)習(xí) JSP 在群里爭論了一番。他的想法是一定要學(xué),并且還羅列了一個讓我哭笑不得的理由,那就是“學(xué)習(xí) JSP 可以加深對Servlet原理的理解!”。當時,我整個人都蒙了,就很氣憤??!這位群友也是工作一年多的人了,不知道為啥會說出這樣的話。
本來準備自己寫一篇文章來回懟,后面看了陳龍大佬也寫了一篇類似的文章,看完之后感覺非常不錯。于是,轉(zhuǎn)載過來,希望對大家有幫助。
自從在知乎回答問題以來,以及根據(jù)最近幾年給企業(yè)做技術(shù)咨詢的情況,發(fā)現(xiàn) JSP 還是一個經(jīng)常被提到的問題。希望能在這篇文章里把關(guān)于 JSP 的問題集中說明一下。我的觀點很明確,已經(jīng)寫在文章標題里了。
確實,很多初學(xué)者,甚至是學(xué)了一兩年的 Java 程序員還在糾結(jié)是否要學(xué) JSP。我認為如非工作需要,別學(xué)!
還是老規(guī)矩,有任何疑問都可以在評論區(qū)提出來,有時間我一定會解答。我會把典型問題提取到文章正文里,讓更多人看到。有任何錯誤,包括錯字、語句不通順等問題,敬請指正。
我 1998 年開始學(xué)習(xí) Java,那時候?qū)W校里老師可能聽說過 Java,但是同學(xué)基本上都不知道 Java。校圖書館進第一批 Java 的書,后面的借閱記錄上都是我的名字。當時幾乎所有男同學(xué)都在學(xué) C++、PB、VB、Delphi,女生很多在學(xué) ASP。所以很多同學(xué)問我學(xué)的是什么,Java 是干什么的。
大學(xué)畢業(yè)以后,開始用 Java 做的第一個實際項目是對日外包,是 2001 年。日方有一套很老的系統(tǒng),想用 Java 重構(gòu)一下,要求用 JSP。我下班就跑去西單圖書大廈,發(fā)現(xiàn)那里的書都還是 Servlet 的, 沒有 JSP 的!
還好,當時的公司同時進行的一項業(yè)務(wù)就是代理 BEA 的 Weblogic(BEA 是三個從 SUN 出來的人創(chuàng)建的,后來被 Oracle 收購)。Weblogic 的產(chǎn)品文檔里包含非常全面的 JSP 介紹,所以起初對 JSP 的學(xué)習(xí)都是從 Weblogic 開始的。
那時候還沒聽說過什么 Struts。自己在 SUN 的官網(wǎng)發(fā)現(xiàn)了 WAF 的文檔,全稱是 Web Application Framework,算是最早 MVC 模式的介紹。這個 WAF 不算是框架,只是介紹了 MVC 模式應(yīng)該是個什么樣子,如何用 Servlet+JSP 實現(xiàn) MVC 模式。SUN 的官網(wǎng)提供了少量的樣例代碼,剩下的都是我們根據(jù)文檔自己搭建和實踐。
在項目的中后期(02 年下半年吧),有一次坐班車,聽到后面座位上兩個人在說話。
一個人問:你知道 Struts 嗎?另外一個人說:不知道。問的那個人說:就是 S T R U T S 這幾個字母,開發(fā) Java 的。我偷偷記在心里,然后第二天上網(wǎng)查了一下(當時沒有智能機,家里也沒有 WIFI),才算開啟了 Apache 這扇大門。后來在 ASF 上又學(xué)習(xí)了 Cocoon、pluto、turbine 等等很多框架。
大概 02 年底,對日外包項目順利完成了,我公司開始接國內(nèi)的項目。第一個國內(nèi)項目是東北一所大學(xué)的科研經(jīng)費審批項目。記得去給人家部署和演示的時候特別有意思。我們用了半天時間在服務(wù)器上部署好,然后去給客戶演示。打開瀏覽器,輸入 ip+端口,開始操作。操作了十幾分鐘,所有的客戶沒有說一個字。越演示心里越?jīng)]底,不知道客戶啥反應(yīng)。大概又過了幾分鐘,客戶的主任發(fā)話了:你們的軟件呢?
我們的軟件呢?我給你演示了半天,這不就是我們的軟件嗎?最后才明白,用戶認為只有下載一個類似叫 setup.exe 或 install.exe 的程序,雙擊,然后下一步下一步,最后桌面上出現(xiàn)一個快捷方式,那才算是軟件!在經(jīng)過片刻的不可思議之后,我認為實際用戶的理念總是落后于研發(fā)人員的理念,這個我很容易想明白。但后來發(fā)現(xiàn),我那些學(xué) PB、Delphi 的師兄弟也不是一時半會能接受 B/S 結(jié)構(gòu)的應(yīng)用算是軟件的...他們認為:你不就是寫個網(wǎng)頁嗎???
再后來,從 03-08 年,長期從事企業(yè)應(yīng)用開發(fā),主要是基于 Weblogic Platform,包括 Server、Integration、Portal,其中在 Portal 上工作的時間最多。
其中 04-05 年用 Weblogic Portal 做深圳市最大的電子政務(wù)項目,06-07 年用 Weblogic 平臺做廣東省電信的 3G 業(yè)務(wù)平臺,08-09 年用 Aqualogic 做南方電網(wǎng)的 SOA。
Weblogic Server 中集成了 Struts,沒記錯的話當時是 1.1 版本。BEA 把 Struts 做了升級和改造,可以在 Weblogic Workshop 中可視化開發(fā),就是下面這樣:
其中圓形代表 Action,有 Begin Action,End Action,還有普通的中間節(jié)點 Action。BEA 把 Struts 的這個升級稱作 Java Page Flow(Java 頁面流)。一組這樣的圖形當中包含的 Action 和 JSP,會定義在一個擴展名是.jpf 的文件中。
后來,BEA 把 JPF 捐獻給了 Apache,成為 ASF 下的一個開源項目Apache Beehive。
這個項目現(xiàn)在已經(jīng)停止更新了。
大概從 06 年開始,接觸到了 YUI,也就是 Yahoo User Interface,Yahoo 開源的一套前端 JS 組件庫。從此算是開啟了我的前端之路。
07-08 年開始用 Extjs,作者說 Ext 就是 Extension(擴展)的意思,擴展了 YUI,提供了更豐富的適合企業(yè)開發(fā)的前端組件。但這時候,Extjs 還僅僅是豐富的 UI 組件庫,算不上框架。就是在 JSP 生成的 HTML 里面嵌入 Extjs 的組件。
09-11 年用 GWT,就是 Google Web Toolkits。Google 當時的想法很先進,用 Java 開發(fā)前端 UI,最終編譯成 JS。有點類似于現(xiàn)在 TS 編譯成 JS 的過程,就是打算利用上 Java 的強類型、面向?qū)ο蟮忍攸c。這時候就已經(jīng)完全前后端分離了。可以說從 08 年之后我就再也沒寫過 JSP,一個頁面也沒寫過。
10 年開始用 Bootstrap。這時候 GWT 的缺點就暴露出來了,CSS 非常難改。直到 13 年初,開始用上了 Angularjs。記得當時在智聯(lián)招聘上發(fā)布職位的時候搜了一下,北京市只有用友和我們公司招聘 Angularjs 開發(fā)。后來就從 Angularjs 用到 React,又用回 Angular4,一直到現(xiàn)在都以最新版本的 Angular 為主,企業(yè)應(yīng)用和互聯(lián)網(wǎng)應(yīng)用都有開發(fā)。移動開發(fā)主要用 Ionic,React Native 也用過。
為什么要詳細介紹我過去和 JSP 以及前端框架相關(guān)的開發(fā)經(jīng)歷呢?是因為我想表達一個觀點:如果要客觀公正評價 JSP 是否還有必要用,特別是還有必要學(xué),需要一個真正長期用過 JSP(前后端不分離)開發(fā),也真正長期用前端框架(前后端分離)開發(fā)的人才可以。
就像我在有些知乎答案下評論的那樣:
遇到這種情況,我總想起福特的名言:“如果我當年去問顧客他們想要什么,他們肯定會告訴我:‘一匹更快的馬?!?/span>
滿大街跑馬車的時代,福特問顧客需要什么,顧客就說需要一匹更快的馬。他們不知道汽車時代會給生活帶來怎樣革命性的變化。
在 BP 機時代,大家認為有人戴 BP 機已經(jīng)很牛了。滿大街諾基亞摩托羅拉功能機的時代,大家也都覺得夠用了。問他們需要什么,他們估計會回答:充一次電能不能待機一個月?能不能把自己喜歡的 MP3 當彩鈴?
我覺得要對比評價兩代產(chǎn)品,應(yīng)該給兩代產(chǎn)品都熟練體驗過的人去判斷。從功能機時代過來的人,現(xiàn)在 iphone 都已經(jīng)用到第三部了,你再問他功能機夠不夠用。就拿一個兩代產(chǎn)品都具有的功能(比如都可以 QQ 聊天)對比,你愿意回到功能機時代還是繼續(xù)用智能機。
一直抱定 JSP 不撒手,沒動力、沒能力學(xué)習(xí)前端技術(shù),沒有真正理解前后端分離開發(fā)模式的人,不可能得出公正全面的評價。
在校期間或參加培訓(xùn)班就學(xué)習(xí)了前端框架,參加工作后就開始前后端分離的人,也無法理解老人只用 JSP 或用 JSP+JS 前端 UI 組件的開發(fā)模式是個怎么回事。
上面兩種人,據(jù)我實際接觸中了解,大部分都認為自己的開發(fā)模式是理所當然的。
就像我之前描述自己剛畢業(yè)時候的經(jīng)歷一樣。大部分客戶和我的一些同學(xué),理所當然認為雙擊 setup.exe,然后下一步下一步才是軟件。而我理所當然認為 B/S 架構(gòu)的也是軟件,只是更便于開發(fā)和操作。
過去一年多,陸陸續(xù)續(xù)在知乎上回答了一些關(guān)于 JSP 的問題。當然,我的回答都是建議淘汰 JSP,新人小白一定不要再學(xué) JSP 了。我現(xiàn)在集中把這些技術(shù)因素歸納一下。
一個現(xiàn)代主流 Java Web 應(yīng)用,不管前端、后端、還是微服務(wù)架構(gòu),都在淘汰 JSP。
其中,我認為 Java 服務(wù)器端主流技術(shù)還是 Spring(Spring Boot + Spring MVC + Spring Cloud)。
下面三點,第一點幾乎盡人皆知,第二點有一部分人清楚,第三點卻很少有人意識到。
1.前端框架已經(jīng)非常成熟和穩(wěn)定,不需要 JSP
前后端分離已經(jīng)不是什么趨勢了,而是當前 B/S 架構(gòu)開發(fā)的主流模式。前后端分離之后,前端只負責(zé)展現(xiàn)和交互,后端負責(zé)核心業(yè)務(wù)邏輯。前后端通過 API 進行交互,并且最好符合 RESTful 風(fēng)格。服務(wù)器端把數(shù)據(jù)返回給前端就不再關(guān)心這些數(shù)據(jù)用在哪里、如何布局、什么樣式。
這個層面的原因非常容易理解,也是絕大多數(shù)討論 JSP 是否還有必要學(xué)的時候里都會提到的。
2.服務(wù)器端的 Spring MVC/WebFlux 和 Spring Boot 已經(jīng)開始拋棄 JSP
從 Spring 5 開始,在原有的基于 Servlet 技術(shù)的 Spring MVC 之外增加了一個新的編程模型,就是 Spring WebFlux。
Spring WebFlux 是響應(yīng)式非阻塞的,而且不支持 Servlet API,所以也就不支持 JSP!
上圖左側(cè)是 Spring 5 新引入的 Spring WebFlux,右側(cè)是大家熟悉的 Spring MVC,兩者并列,Spring 同時支持。
關(guān)于這一點,可以看 Stack Overflow 上面來自 Spring Framework 和 Spring Boot 團隊成員 Brian Clozel 的回答:
https://stackoverflow.com/questions/46970379/spring-webflux-no-jsp-support?rq=1
很多人可能又會說了:新的 Spring WebFlux 不支持 JSP,那咱們不用就好了,至少 Spring MVC 還是支持 JSP 的啊。那我們繼續(xù)看。
如果我們繼續(xù)使用 Spring Boot+Spring MVC 開發(fā),那么 Spring Boot 對 JSP 是有限制的,看官方文檔怎么說的:
鏈接在這里:https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-template-engines
其中那行備注:
If possible, JSPs should be avoided. There are several known limitations when using them with embedded servlet containers.盡可能避免用 JSP。當使用嵌入式 Servlet 容器時,有一些已知的限制。
關(guān)于這些限制和如何繼續(xù)在 Spring Boot 中使用 JSP,可以自己查一下,知乎里就有好多文章。
Spring Boot 對 JSP 有限制,那咱們就湊合用唄,反正我是寫 Java 的,我的發(fā)展方向是架構(gòu)師,我正打算學(xué)習(xí)微服務(wù),正在看 Spring Cloud。那咱們就繼續(xù)看看 Spring Cloud 吧。
3.微服務(wù)架構(gòu)下更沒有 JSP 的用武之地
首先要明白 Spring Boot 和 Spring Cloud 的關(guān)系,看這張圖吧:
右側(cè)綠色的部分都是 Spring Cloud 的組成部分,不管是 API Gateway、Config Dashboard,Service Registry,還是多個 MicroServices,他們都是 Spring Boot 應(yīng)用!或者說 Spring Boot 是整個 Spring Cloud 的基石(其實也是 Spring Cloud Data Flow 的基石)。
哦,你明白了,因為有 Spring Boot 對 JSP 的限制,而 Spring Cloud 的組成部分都是 Spring Boot 應(yīng)用,所以 Spring Cloud 也對 JSP 有限制。其實不僅僅是表面上這個原因,咱們繼續(xù)分析。
如果強行繼續(xù)在 Spring Cloud 環(huán)境中繼續(xù)使用 JSP,那么 JSP 放在哪里?有兩種方案。
- API Gateway 和每個 MicroService 里面都有@Controller以及對應(yīng)的 JSP。那么這種方案下,不同微服務(wù)中的 JSP 如何通信?用戶訪問的時候,同一個應(yīng)用下的所有 JSP 頁面會在不同 IP 和端口下來回變換。一會是http://ip0:8081/xxx/xxx.jsp,一會是http://ip1:8082/xxx/xxx.jsp,點個連接又跳轉(zhuǎn)到http://ip2:8080/xxx/xxx.jsp....
- 把整個微服務(wù)應(yīng)用下的所有@Controller和 JSP 都放在 API Gateway 里面,其他 Microservice 中只有提供 REST API 的@Controller和@Service。這種方案并不算理想的微服務(wù)架構(gòu),因為 Gateway 沒有解耦,里面的所有@Controller不能拆分部署。這樣就相當于在 MicroService 架構(gòu)下有了一個局部的 Monolithic(單體應(yīng)用)。
那怎么才算是使用 Spring Cloud 的正確姿勢?還是看上面那幅圖,這次關(guān)注左側(cè)三個灰色的部分。IoT(物聯(lián)網(wǎng) Internet of Things)、Mobile(移動應(yīng)用)、Browser(瀏覽器端),這三個也是應(yīng)用啊。
我們再看一幅圖:
整個 Spring 體系的圖出來了。還是看左側(cè),Your App,也就是 IoT(物聯(lián)網(wǎng) Internet of Things)、Mobile(移動應(yīng)用)、Browser(瀏覽器端)這三類!
Browser 就是前后端分離之后的前端應(yīng)用,獨立開發(fā)、獨立部署、只和服務(wù)器端有 HTTP RESTful 通信。
我們看看 Spring 官方給出的 Spring Cloud 例子,鏈接在這里:https://spring.io/projects/spring-cloud#samples 。
customers-stores-ui 是前端應(yīng)用,用 Angularjs 實現(xiàn)的。例子是便于學(xué)習(xí)的,不應(yīng)該引入額外的太多其他技術(shù)!為什么 Spring 官方的例子非要用上前端技術(shù)?不能只用服務(wù)器端開發(fā)人員熟悉的模板引擎(包括 JSP)來演示 Spring Cloud 嗎?
我們再看另外一個例子,Spring 的 Petclinic 大家都熟悉吧?Spring 官方例子:https://github.com/spring-projects/spring-petclinic 。
官方的是 Monolithic(單體)應(yīng)用,模板用的是 Thymeleaf,自己去看代碼。
用 Spring Cloud 實現(xiàn)的版本:https://github.com/spring-petclinic 。
前端有 Angular 和 React 兩種實現(xiàn),服務(wù)器端有 Java 和 Kotlin 兩種實現(xiàn),都沒有用服務(wù)器端模板。
同樣的問題。為什么演示 Spring Cloud 的開發(fā),要引入額外的前端技術(shù)?
答案都是同樣的,Spring Cloud 就必須前后端分離開發(fā)!用 JSP 就無法完美拆分微服務(wù),無法利用微服務(wù)本應(yīng)帶來的各種優(yōu)勢。
總結(jié):
我曾經(jīng)在知乎某一個問題下總結(jié)過:現(xiàn)在 JSP 處于被前后端夾擊的狀態(tài),生存空間越來越小了。就算你不打算管前端,只想在服務(wù)器端有所建樹。微服務(wù)的前提也必須前后端分離。
放棄 JSP 吧,讓自己的路走的寬一些。如果死守 JSP 不放,服務(wù)器端只能停留在 SSH/SSM 階段,用 Spring Boot+Spring MVC 已經(jīng)是你的天花板了。
來源:https://zhuanlan.zhihu.com/p/71937497
*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。