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