自從在知乎回答問題以來,以及根據最近幾年給企業做技術諮詢的情況,發現JSP還是一個經常被提到的問題。希望能在這篇文章里把關於JSP的問題集中說明一下。我的觀點很明確,已經寫在文章標題里了。

還是老規矩,有任何疑問都可以在評論區提出來,有時間我一定會解答。我會把典型問題提取到文章正文里,讓更多人看到。有任何錯誤,包括錯字、語句不通順等問題,敬請指正。

先說一下我自己學習和使用JSP的經歷吧

我1998年開始學習Java,那時候學校里老師可能聽說過Java,但是同學基本上都不知道Java。校圖書館進第一批Java的書,後面的借閱記錄上都是我的名字。當時幾乎所有男同學都在學C++、PB、VB、Delphi,女生很多在學ASP。所以很多同學問我學的是什麼,Java是幹什麼的。

大學畢業以後,開始用Java做的第一個實際項目是對日外包,是2001年。日方有一套很老的系統,想用Java重構一下,要求用JSP。我下班就跑去西單圖書大廈,發現那裡的書都還是Servlet的, 沒有JSP的!

還好,當時的公司同時進行的一項業務就是代理BEA的Weblogic(BEA是三個從SUN出來的人創建的,後來被Oracle收購)。Weblogic的產品文檔里包含非常全面的JSP介紹,所以起初對JSP的學習都是從Weblogic開始的。

那時候還沒聽說過什麼Struts。自己在SUN的官網發現了WAF的文檔,全稱是Web Application Framework,算是最早MVC模式的介紹。這個WAF不算是框架,只是介紹了MVC模式應該是個什麼樣子,如何用Servlet+JSP實現MVC模式。SUN的官網提供了少量的樣例代碼,剩下的都是我們根據文檔自己搭建和實踐。

在項目的中後期(02年下半年吧),有一次坐班車,聽到後面座位上兩個人在說話。一個人問:你知道Struts嗎?另外一個人說:不知道。問的那個人說:就是S T R U T S這幾個字母,開發Java的。我偷偷記在心裡,然後第二天上網查了一下(當時沒有智能機,家裡也沒有WIFI),才算開啟了Apache這扇大門。後來在ASF上又學習了Cocoon、pluto、turbine等等很多框架。

大概02年底,對日外包項目順利完成了,我公司開始接國內的項目。第一個國內項目是東北一所大學的科研經費審批項目。記得去給人家部署和演示的時候特別有意思。我們用了半天時間在伺服器上部署好,然後去給客戶演示。打開瀏覽器,輸入ip+埠,開始操作。操作了十幾分鐘,所有的客戶沒有說一個字。越演示心裡越沒底,不知道客戶啥反應。大概又過了幾分鐘,客戶的主任發話了:你們的軟體呢?

我們的軟體呢?我給你演示了半天,這不就是我們的軟體嗎?最後才明白,用戶認為只有下載一個類似叫setup.exe或install.exe的程序,雙擊,然後下一步下一步,最後桌面上出現一個快捷方式,那才算是軟體!在經過片刻的不可思議之後,我認為實際用戶的理念總是落後於研發人員的理念,這個我很容易想明白。但後來發現,我那些學PB、Delphi的師兄弟也不是一時半會能接受B/S結構的應用算是軟體的...他們認為:你不就是寫個網頁嗎???

再後來,從03-08年,長期從事企業應用開發,主要是基於Weblogic Platform,包括Server、Integration、Portal,其中在Portal上工作的時間最多。

其中04-05年用Weblogic Portal做深圳市最大的電子政務項目,06-07年用Weblogic平台做廣東省電信的3G業務平台,08-09年用Aqualogic做南方電網的SOA。

Weblogic Server中集成了Struts,沒記錯的話當時是1.1版本。BEA把Struts做了升級和改造,可以在Weblogic Workshop中可視化開發,就是下面這樣:

其中圓形代表Action,有Begin Action,End Action,還有普通的中間節點Action。BEA把Struts的這個升級稱作Java Page Flow(Java 頁面流)。一組這樣的圖形當中包含的Action和JSP,會定義在一個擴展名是.jpf的文件中。

後來,BEA把JPF捐獻給了Apache,成為ASF下的一個開源項目Apache Beehive。

Welcome to Apache Beehive?

beehive.apache.org

這個項目現在已經停止更新了。

大概從06年開始,接觸到了YUI,也就是Yahoo User Interface,Yahoo開源的一套前端JS組件庫。從此算是開啟了我的前端之路。

07-08年開始用Extjs,作者說Ext就是Extension(擴展)的意思,擴展了YUI,提供了更豐富的適合企業開發的前端組件。但這時候,Extjs還僅僅是豐富的UI組件庫,算不上框架。就是在JSP生成的HTML裡面嵌入Extjs的組件。

09-11年用GWT,就是Google Web Toolkits。Google當時的想法很先進,用Java開發前端UI,最終編譯成JS。有點類似於現在TS編譯成JS的過程,就是打算利用上Java的強類型、面向對象等特點。這時候就已經完全前後端分離了。可以說從08年之後我就再也沒寫過JSP,一個頁面也沒寫過。

10年開始用Bootstrap。這時候GWT的缺點就暴露出來了,CSS非常難改。直到13年初,開始用上了Angularjs。記得當時在智聯招聘上發布職位的時候搜了一下,北京市只有用友和我們公司招聘Angularjs開發。後來就從Angularjs用到React,又用回Angular4,一直到現在都以最新版本的Angular為主,企業應用和互聯網應用都有開發。移動開發主要用Ionic,React Native也用過。

為什麼要詳細介紹我過去和JSP以及前端框架相關的開發經歷呢?是因為我想表達一個觀點:如果要客觀公正評價JSP是否還有必要用,特別是還有必要學,需要一個真正長期用過JSP(前後端不分離)開發,也真正長期用前端框架(前後端分離)開發的人才可以。

就像我在有些知乎答案下評論的那樣:

遇到這種情況,我總想起福特的名言:「如果我當年去問顧客他們想要什麼,他們肯定會告訴我:『一匹更快的馬。』」

滿大街跑馬車的時代,福特問顧客需要什麼,顧客就說需要一匹更快的馬。他們不知道汽車時代會給生活帶來怎樣革命性的變化。

在BP機時代,大家認為有人戴BP機已經很牛了。滿大街諾基亞摩托羅拉功能機的時代,大家也都覺得夠用了。問他們需要什麼,他們估計會回答:充一次電能不能待機一個月?能不能把自己喜歡的MP3當彩鈴?

我覺得要對比評價兩代產品,應該給兩代產品都熟練體驗過的人去判斷。從功能機時代過來的人,現在iphone都已經用到第三部了,你再問他功能機夠不夠用。就拿一個兩代產品都具有的功能(比如都可以QQ聊天)對比,你願意回到功能機時代還是繼續用智能機。

一直抱定JSP不撒手,沒動力、沒能力學習前端技術,沒有真正理解前後端分離開發模式的人,不可能得出公正全面的評價。

在校期間或參加培訓班就學習了前端框架,參加工作後就開始前後端分離的人,也無法理解老人只用JSP或用JSP+JS前端UI組件的開發模式是個怎麼回事。

上面兩種人,據我實際接觸中了解,大部分都認為自己的開發模式是理所當然的。就像我之前描述自己剛畢業時候的經歷一樣。大部分客戶和我的一些同學,理所當然認為雙擊setup.exe,然後下一步下一步才是軟體。而我理所當然認為B/S架構的也是軟體,只是更便於開發和操作。

JSP為什麼不適合現在的主流開發,為什麼正在被拋棄

過去一年多,陸陸續續在知乎上回答了一些關於JSP的問題。當然,我的回答都是建議淘汰JSP,新人小白一定不要再學JSP了。我現在集中把這些技術因素歸納一下。

一個現代主流Java Web應用,不管前端、後端、還是微服務架構,都在淘汰JSP。

其中,我認為Java伺服器端主流技術還是Spring(Spring Boot + Spring MVC + Spring Cloud)。

下面三點,第一點幾乎盡人皆知,第二點有一部分人清楚,第三點卻很少有人意識到。

前端框架已經非常成熟和穩定,不需要JSP

前後端分離已經不是什麼趨勢了,而是當前B/S架構開發的主流模式。前後端分離之後,前端只負責展現和交互,後端負責核心業務邏輯。前後端通過API進行交互,並且最好符合RESTful風格。伺服器端把數據返回給前端就不再關心這些數據用在哪裡、如何布局、什麼樣式。

這個層面的原因非常容易理解,也是絕大多數討論JSP是否還有必要學的時候里都會提到的。

伺服器端的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的回答:

Spring WebFlux - no JSP support??

stackoverflow.com
圖標

新的Spring WebFlux不支持JSP,那咱們不用就好了,至少Spring MVC還是支持JSP的啊。那我們繼續看。

如果我們繼續使用Spring Boot+Spring MVC開發,那麼Spring Boot對JSP是有限制的,看官方文檔怎麼說的:

鏈接在這裡:

Spring Boot Reference Guide?

docs.spring.io

其中那行備註:

If possible, JSPs should be avoided. There are several known limitations when using them with embedded servlet containers.

儘可能避免用JSP。當使用嵌入式Servlet容器時,有一些已知的限制。

關於這些限制和如何繼續在Spring Boot中使用JSP,可以自己查一下,知乎里就有好多文章

Spring Boot對JSP有限制,那咱們就湊合用唄,反正我是寫Java的,我的發展方向是架構師,我正打算學習微服務,正在看Spring Cloud。那咱們就繼續看看Spring Cloud吧。

微服務架構下更沒有JSP的用武之地

首先要明白Spring Boot和Spring Cloud的關係。可以先看我的這個回答:Spring boot與Spring cloud 是什麼關係??

www.zhihu.com
圖標

還是看這張圖吧:

右側綠色的部分都是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有限制。其實不僅僅是表面上這個原因,咱們繼續分析。

如果強行繼續在Spring Cloud環境中繼續使用JSP,那麼JSP放在哪裡?有兩種方案。

  1. API Gateway和每個MicroService裡面都有@Controller以及對應的JSP。那麼這種方案下,不同微服務中的JSP如何通信?用戶訪問的時候,同一個應用下的所有JSP頁面會在不同IP和埠下來回變換。一會是ip0:8081/xxx/xxx.jsp,一會是ip1:8082/xxx/xxx.jsp,點個連接又跳轉到ip2:8080/xxx/xxx.jsp.
  2. 把整個微服務應用下的所有@Controller和JSP都放在API Gateway裡面,其他Microservice中只有提供REST API的@Controller和@Service。這種方案並不算理想的微服務架構,因為Gateway沒有解耦,裡面的所有@Controller不能拆分部署。這樣就相當於在MicroService架構下有了一個局部的Monolithic(單體應用)。

那怎麼才算是使用Spring Cloud的正確姿勢?還是看上面那幅圖,這次關注左側三個灰色的部分。IoT(物聯網 Internet of Things)、Mobile(移動應用)、Browser(瀏覽器端),這三個也是應用啊。

我們再看一幅圖:

整個Spring體系的圖出來了。還是看左側,Your App,也就是IoT(物聯網 Internet of Things)、Mobile(移動應用)、Browser(瀏覽器端)這三類!

Browser就是前後端分離之後的前端應用,獨立開發、獨立部署、只和伺服器端有HTTP RESTful通信。

我們看看Spring官方給出的Spring Cloud例子,鏈接在這裡:

Spring Projects?

spring.io圖標

customers-stores-ui是前端應用,用Angularjs實現的。例子是便於學習的,不應該引入額外的太多其他技術!為什麼Spring官方的例子非要用上前端技術?不能只用伺服器端開發人員熟悉的模板引擎解(包括JSP)來演示Spring Cloud嗎?

我們再看另外一個例子,Spring的Petclinic大家都熟悉把?Spring 官方例子:

spring-projects/spring-petclinic?

github.com
圖標

官方的是Monolithic(單體)應用,模板用的是Thymeleaf,自己去看代碼。

用Spring Cloud實現的版本:

Spring Petclinic community?

github.com
圖標

前端有Angular和React兩種實現,伺服器端有Java和Kotlin兩種實現,都沒有用伺服器端模板。

同樣的問題。為什麼演示Spring Cloud的開發,要引入額外的前端技術?

答案都是同樣的,Spring Cloud就必須前後端分離開發!用JSP就無法完美拆分微服務,無法利用微服務本應帶來的各種優勢。

總結:

我曾經在知乎某一個問題下總結過:現在JSP處於被前後端夾擊的狀態,生存空間越來越小了。就算你不打算管前端,只想在伺服器端有所建樹。微服務的前提也必須前後端分離。

放棄JSP吧,讓自己的路走的寬一些。如果死守JSP不放,伺服器端只能停留在SSH/SSM階段,用Spring Boot+Spring MVC已經是你的天花板了。

附錄,之前在知乎回答的相關問題:

到底什麼是前後端分離??

www.zhihu.com圖標Java新手如何學習Spring、Struts、Hibernate三大框架??

www.zhihu.com
圖標
為什麼都在說初學者可以不要學Jsp,但網路上的教程都還是在用JSP??

www.zhihu.com
圖標
Spring cloud寫的微服務 前端方面應該如何解決??

www.zhihu.com
圖標
SpringCloud項目的前端用什麼技術?可以和SSM的前端是一樣的嗎??

www.zhihu.com
圖標
Java Web 開發使用 jsp 頁面是否已經落後了?是的話現在流行用什麼??

www.zhihu.com
圖標
Spring cloud寫的微服務 前端方面應該如何解決??

www.zhihu.com
圖標

推薦閱讀:

相关文章