再见 JSP !

作者:陈龙@知乎

来源:zhuanlan.zhihu.com/p/71937497


自从在知乎回答问题以来,以及根据最近几年给企业做技术咨询的情况,发现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 Beehivbeehive.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 supportstackoverflow.com

新的Spring WebFlux不支持JSP,那咱们不用就好了,至少Spring MVC还是支持JSP的啊。那我们继续看。

如果我们继续使用Spring Boot+Spring MVC开发,那么Spring Boot对JSP是有限制的,看官方文档怎么说的:

链接在这里:

Spring Boot Reference Guiddocs.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,可以自己查一下,知乎里就有好多文章。

关注微信公众号 Java后端,回复 666 获取 PDF 版本 Spring Boot 技术博文下载链接。

Spring Boot对JSP有限制,那咱们就凑合用呗,反正我是写Java的,我的发展方向是架构师,我正打算学习微服务,正在看Spring Cloud。那咱们就继续看看Spring Cloud吧。

微服务架构下更没有JSP的用武之地  

首先要明白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(单体应用)。关注公众号Java大后端,回复关键字资料,获取最新架构资料。

那怎么才算是使用Spring Cloud的正确姿势?还是看上面那幅图,这次关注左侧三个灰色的部分。IoT(物联网 Internet of Things)、Mobile(移动应用)、Browser(浏览器端),这三个也是应用啊。

我们再看一幅图:

整个Spring体系的图出来了。还是看左侧,Your App,也就是IoT(物联网 Internet of Things)、Mobile(移动应用)、Browser(浏览器端)这三类!

Browser就是前后端分离之后的前端应用,独立开发、独立部署、只和服务器端有HTTP RESTful通信。

我们看看Spring官方给出的Spring Cloud例子,链接在这里:

Spring Projectspring.io

customers-stores-ui是前端应用,用Angularjs实现的。例子是便于学习的,不应该引入额外的太多其他技术!为什么Spring官方的例子非要用上前端技术?不能只用服务器端开发人员熟悉的模板引擎解(包括JSP)来演示Spring Cloud吗?

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

spring-projects/spring-petclinigithub.com

官方的是Monolithic(单体)应用,模板用的是Thymeleaf,自己去看代码。

用Spring Cloud实现的版本:

Spring Petclinic communitgithub.com

前端有Angular和React两种实现,服务器端有Java和Kotlin两种实现,都没有用服务器端模板。

同样的问题。为什么演示Spring Cloud的开发,要引入额外的前端技术?

答案都是同样的,Spring Cloud就必须前后端分离开发!用JSP就无法完美拆分微服务,无法利用微服务本应带来的各种优势。

总结

我曾经在知乎某一个问题下总结过:现在JSP处于被前后端夹击的状态,生存空间越来越小了。就算你不打算管前端,只想在服务器端有所建树。微服务的前提也必须前后端分离。

放弃JSP吧,让自己的路走的宽一些。如果死守JSP不放,服务器端只能停留在SSH/SSM阶段,用Spring Boot+Spring MVC已经是你的天花板了。

END


【推荐阅读

一个基于 Spring Boot 的项目骨架

一口气说出 9 种分布式 ID 生成方式,面试官有点懵了

老板说用 float 存储金额的损失从工资里扣!

推荐一款 IDEA 生成代码神器,写代码再也不用加班了!

Spring Cloud 入门总结

再见,Navicat!这个IDEA的兄弟,真香!

JAVA 线上故障排查完整套路!牛掰!

你可能感兴趣的:(再见 JSP !)