在我自学JavaWeb有两个地方我觉得最难,一个是JDBC相关内容,另一个是JSP与Servlet。JSP本质也是Servlet,所以关于Servlet这里只带了一笔,默认大家都会。
JDBC让我感到困难的原因是,JDBC这是我接触的第一个非Java以类形式的知识点。它是一个界面,而不是以前学过的Java类。这让我好久没有放慢脚步了。什么是界面?JDBC做接口有什么好处?JavaWeb中几次jdbcUtils的封装、JDBC QueryRunner ThreadLocal很难一起实现事务等知识点。(建议大家跟上jdbcUtils几次演变)
Servlet与JSP的难点在于概念太多、太杂、太抽象。首先,你要过好几天才明白它是个什么东西、用来干嘛。其次,等你终于明白它是什么时,你又纳闷它整个流程是怎样的。就好比我现在问你,从浏览器地址栏键入url向服务器响应数据发起请求,中间Servlet和JSP你知道他们都做了什么吗?另一个是JSP比Servlet更容易让人困惑,以至于我曾经以为是,JSP它在客户端而不是服务器端运行...等等,现在我想我可能会觉得云很轻,但这对我当时来说是一个痛苦的蛋。此外,杭州7月和8月非常热,可以说:暖风让游客喝醉,直接把桌子当床睡觉。
和前几篇文章一样,这篇文章大多是概念解释。就我个人而言,我不是很冷。所谓的碎片化学习只是自欺欺人。所以读完这篇文章后,坐下来静静地学习需要时间。
主要内容介绍:
动乱年代JSP是什么一个Http请求冒险JSP与AJAX HTMLMVC模式与J ** AEE动乱时代的三层架构在介绍JSP以前一定要先讲英雄的故事。
19872007年9月14日21时07分,有人从北京向海外发一封电子邮件。邮件内容为Across the GreatWall we can reach every corner in the world(穿越长城,走向世界),这表明互联网时代悄然敲响了中国的大门。
让我们把目光从中国转移到海外。20世纪90年代,当时的互联网还在开放,一片混乱。1995年和接下来的一年,可以说是群雄争鹿,注定不平凡。当时我还在家玩泥巴。
1995年5月,SUN公司发布了Java。这个名字很随意,据说是因为创始人正好在咖啡店里讨论取什么名字。其中一个看着手里的咖啡,突然灵机一动: ** ,就叫Java嗯。这就像在农村生孩子,爸爸看,** ,这孩子的骨头很惊讶,脸也很漂亮,叫...二狗子吧,的感觉一样一样的。几乎同年,也不知道稍早还是稍晚,反正不重要,PHP它也发布了。当时人们不知道它会被黑为世界上最好的语言。第二年,一个叫布兰登的人·艾奇(Brendan Eich,1961年~)应老板要求,技术人员花了10天时间学习几种语言的优秀特点(包括Java),写出了LiveScript。在发布时擦拭Java热度扩大宣传,不惜改名JavaScript。所谓慢工出细活,所以...JavaScript只写了10多天,自然是...幸运的是,它后来得救了。现在至少是这样GitHub提交量最大的语言,近年来前端也很受欢迎。
我们知道浏览器可以通过分析进行分析html句子渲染页面。
关键是这些html句子是怎么来的?浏览器需要通过吗?http根据浏览器的要求,请求页面,然后服务器通过http响应相应的页面html句子回我们用服务器端?Java开发,它用什么响应这么多?html语句?答案就是:Servlet!
随手用MyEclipse新建一个Servlet,你会看到,生成Servlet默认模板如下:
可以看到Servlet的doGet()和doPost()方法体内有响应html片段代码。这实际上是古代发展习惯的遗迹。2018年,MyEclipse我以为你会很聪明Servlet中手动输出HTML片段。的确,在早期JavaWeb在开发过程中,我们的程序猿祖先确实有这样一段黑暗的时光,但那是因为当时没有那么多有用的模板和框架。
在古代,艺术家通常写得很好html静态页面后,扔给Java程序员。Java程序猿在Servlet中调用Service拿到数据后,逐句 ** html静态页面html语句到Servlet在中间,根据情况将后端数据与html片段拼接在一起,然后像
out.println("<span>用户名是:" user.age <"/span>");疯狂输出的方式。
把html代码从页面 ** 到Servlet,在Servlet中拼接数据再响应输出这样,拼接数据并完全输出数据html页面没有几百上千行。out.println()是不可能的。所以基本上敲完两页两指就麻木了。
而同时期的PHP,http://ASP.Net就好多了,人家根本不搞你这个繁琐的一套。他们选择html将相应的语言嵌入页面引入动态数据,避免手动复制html片段输出的尴尬局面。
直接在html在页面中写代码插入数据因为仔细想想,我们的主要目的是最终输出html后台数据嵌入代码中。除了把它放在代码里。html拿出句子Servlet在输出之前,我们也可以直接拼接html动态数据写请注意,不是HTML必须是文件JSP动态模板文件等HTML语句)。这两种设计思路几乎完全相反!
不用我说。
图片来自网络一部分Java程序员一看,就傻眼了:我靠,PHP这是世界上最好的语言,Web开发太简单了!老子再也不想 ** 粘贴!于是转向PHP或者其他语言的开发。就这样,Java失去了一些程序员。SUN公司一看,这不行,Java也要搞一个。于是,JSP应运而生。
JSP是个啥JSP全称Java Server Page,直译是运行在服务器端的页面。上面已经介绍过了,我们可以直接JSP文件里写HTML使用代码时,将其视为代码HTML文件。而且JSP中HTML/CSS/JS等的写法和HTML文件中的写法完全一样。但毕竟不是。HTML,而且本质差了十万八千里。因为我们也可以把它放在一边Java代码内嵌在JSP在页面中,将动态数据渲染成静态页面非常方便。这一点,HTML打死都做不到。
当有人请求JSP当服务器内部经历动态资源时,(JSP)到静态资源(HTML)服务器将自动帮助我们转换JSP中的HTML将片段和数据拼接成静态资源,以响应浏览器。也就是说,JSP在服务器端运行,但最终发送给客户端的是转换HTML静态页面(在响应体中)。
即:JSP = HTML Jav ** 段(各种标签本质上还是Jav ** 段)
记住,1.JSP将动态页面转换为静态页面的服务器端。2.浏览器只能分析静态页面但所谓的“JSP和HTML相似”只是JSP给我们的表面印象。我们必须继续挖下去。事实上,JSP和HTML差远了。JSP本质是一个Java类(Servlet),它与服务器混合,但其输出结果是HTML。蜜蜂生产蜂蜜,但蜜蜂不是蜂蜜!JSP在真身之前,我们先来复习一下什么是真身Servlet。
Servlet是什么?
一个Java类,运行在Servlet容器中(Tomcat)负责接收请求的调用Service处理数据负责响应数据传智播客的图片。真的很好再来看看张孝祥老师的心血之作(感谢网友孤傲苍狼整理):
至此,大家一定是对的Servlet很清楚是什么,主要做什么。接下来,我们来谈谈为什么。JSP本质是一个Servlet。我不会带你去看具体的源代码,我也看不懂。一般流程如下:
WEB容器接收以.jsp为扩展名的URL当访问请求时,它将提交请求JSP处理引擎。Tomcat中的JSP发动机就是其中之一Servlet该程序负责解释和执行JSP页面。每个JSP 页面第一次被访问时,JSP引擎把它翻译成一个Servlet源程序,然后这个Servlet编译成源程序Servlet的class类文件,然后由WEB像调用普通容器Servlet以同样的方式装载和解释执行程序JSP页面翻译Servlet程序。存储位置Tomcat把为JSP页面创建的Servlet源文件和class类别文件放置<TOMCAT_HOME>workCatalina<主机名><应用程序名>”目录中,Tomcat将JSP页面翻译Servlet的包名为org.apache.jsp.<JSP页面在WEB目录名在应用程序中> 。有点晕?来抚摸一下。
本来,我们需要把艺术家放在一起HTML一行代码 ** 到Servlet中间,然后拼接数据,最后响应客户端拼接HTML页面。
对浏览器做出反应HTML语句在http在响应体中,描述返回页面,浏览器根据代码绘制页面后来,我们太麻烦了。JSP,不需要一行 ** HTML代码,但在JSP中直接写HTML代码和Java代码,后期JSP编译成一个Servlet,通过Java代码获取后台数据后拼接HTML最后通过了片段out.println()输出。
现在你可以回答上面的问题:为什么两个完全相反的设计概念已经完成了相同的需求?有很多答案,但其中一个是:这两种方式是相同的,最终实现是相同的,都在同一个Servlet中输出!
我们不妨打开index_jsp.java,观察index.jsp被翻译成Servlet后源码,可见:
也就是说,虽然我们不需要像古代那样手动 ** html语句到Servlet了,但是JSP编译后的Java其实类还在out.println()输出。我们手动 ** 是一样的结果。
而index_jsp.java这类继承HttpJspBase,而HttpJspBase间接实现了Servlet接口。所以可以说,index.jsp被翻译后的Java类也是一个Servlet,所以JSP本质也是一个Servlet。
绕了这么大圈,我们终于明白了:
原来,为了不让Java一行程序员 ** HTML代码到Servlet里,SUN公司干脆让Java程序员直接把HTML写在了Servlet里!但毕竟SUN没那么明目张胆,至少让这个Servlet伪装,打扮成JSP,然后对程序员说:看,我做了个JSP,这家伙很棒,你可以同时在上面写HTML和Java代码哦。是的,等你写完了。JSP,回头看,Tomcat就把这个JSP翻译成Servlet,原先写在JSP里的HTML自动放置代码out.println()里面!相当于程序帮我一行 ** HTML代码到Servlet这一步。(想起来就麻!到目前为止,我们已经知道,JSP就是一个Servlet。所以毫无疑问,不管你将来在哪里JSP看到什么奇怪的东西,只要不报错,说明JSP足够自信把它变成足够自信Java代码的一部分:
要么作为字符串输出(HTML片段片段本身就是Jav ** 段要么转成Jav ** 段(EL没有表达式)EL表达式时Servlet源代码(右图是JSP,左图是JSP编译后的Servlet源码)JSP中添加了EL表达式后,Servlet源码的变化所以,大家千万不要把EL表达式思维太难了。记住语法,知道如何使用它。至于它是如何变成的Java我们需要担心代码吗?
最后提醒一下EL这些表达式标签在何时何地工作。许多人错误地认为这些标签什么时候工作的。EL表达式可以在浏览器中工作。根本原因是对的JSP不了解。JSP是服务器端的,所有操作必须在响应给浏览器之前做完。这些标签,会在JSP文件编译成Servlet自动转化为Java代码,然后处理数据。所以本质上和你在一起。JSP页面写的<%%>之类的Jav ** 段是一样的。它负责从变量(不确定数)中取出数据,变成静态数据后(确定数)贴在薄薄的一张上HTML静态页面。
想象一下,在取出变量之前,数据是立体的,圆鼓的,而且HTML静态页面则薄如一张纸。我们无法在二维面上放入三维物质。而EL表达式从变量取出来的数据则是一个常量,是个字符串一样的东西,可以轻轻地“贴”在HTML里。
至此,我们明白,JSP是立体的机器,在服务器内部,在服务器其他“同僚”的帮助下,生产一张张HTML静态页面让http带回去给浏览器显示。就像吐钞机与钞票的关系。
本质是动态资源到静态资源的转换(省略JSP转为Servlet输出的过程)一个Http请求的冒险之旅JSP与AJAX+HTML其实请求、响应这么一来一回,无非要的就两样东西:数据+HTML骨架。如果把服务器端比作淘宝卖家,客户端(浏览器)比作买家,而数据和HTML则是一件商品的两个重要组成部件。那么我们很自然地能够想到,其实运输方式至少可以有两种:
1.卖家组装好商品后再发货(JSP)
2.卖家把部件拆开,运到之后买家自己组装(AJAX+HTML)
JSP是服务器端的,它的局限性在于数据必须在返回给客户端之前就“装载”完毕。不然HTML都已经发出去了,你就没办法跑到浏览器里把数据给它安上。
而有了AJAX,就可以实现零件发送、目的地组装了。
其实我对前端也不是很熟悉,只能给个大致的图。我至今没搞明白怎么才叫“前后端分离”。不用JSP,改用HTML+AJAX就是前端分离吗?好像也不完全是。以后有更深的体会时,有机会再和大家聊聊这个问题,挺有意思的。
对了,顺便说一句,初学者朋友是不是听说JSP被淘汰了,犹豫要不要学?别闹了,不学JSP你都没法学其他的模板技术。而且,你可能觉得很新奇的free ** rker,其实学过JSP的话,要上手只要几小时。所以,还是有什么学什么,学好才是关键。
再强调一点,虽然我们在浏览器地址栏输入localhost:8080/xxx/xxx.jsp,就显示出了当前页面,但那不是JSP页面,而是HTML页面。服务器并没有直接把JSP文件从服务端扔到客户端!JSP是Java Server Page,是服务器端的东西。服务器的东西永远不可能直接在浏览器运行。浏览器只能接受静态页面。
客户端之所以能显示页面,是因为JSP已经把数据和HTML片段拼凑成完整的静态页面返回给客户端MVC模式与J ** AEE三层架构聊这个,纯粹是因为很多朋友很容易搞错一个概念,认为MVC模式是JavaEE独有的开发模式。其实不是的。MVC是web开发都有的一种模式,比如PHP开发web时也有MVC模式。而三层架构则是JavaEE的:Controller/Service/Dao。分层开发是为了使代码逻辑更加清晰,也起到了一定的解耦合作用。
值得注意的是,MVC只是在web层。当然,如果站在更高的角度,可以看成这样:
参考资料:
1.传智播客崔希凡老师JavaWeb
2.黑马32期郝强勇老师JavaWeb
3.孤傲苍狼博客
2018-8-18 22:36:57
看完本篇文章后,如果希望进一步了解JSP在整个Tomcat中的运行流程,请移步:
JavaWeb(8):Tomcat外传
扫码咨询与免费使用
申请免费使用