日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
版本歷史&代碼示例之Servelt、JSP、EL表達(dá)式

[[423628]]

正文

Servlet

Servlet是一種基于Java的動(dòng)態(tài)Web資源動(dòng)態(tài)Web資源技術(shù),類似的技術(shù)還有ASP、PHP等。

 
 
 
 
  1.  
  2.  
  3.     javax.servlet 
  4.     javax.servlet-api 
  5.     4.0.1 
  6.     provided 
  7.  
  8.  
  9.  
  10.  
  11.     jakarta.servlet 
  12.     jakarta.servlet-api 
  13.     5.0.0 
  14.      
  15.     provided 
  16.  

版本歷史

Servlet規(guī)范由Sun Microsystems公司創(chuàng)建,1.0版于1997年6月完成。從2.3版開(kāi)始,該規(guī)范是在JCP下開(kāi)發(fā)。

版本 發(fā)布日期 隸屬于 JSR版本 焦點(diǎn)說(shuō)明
1.01997.06--首個(gè)版本,由Sun公司發(fā)布
2.01997.08-- 
2.11998.11--新增了RequestDispatcher, ServletContext等
2.21999.08J2EE 1.2-成為J2EE的一部分。在.war文件中引入了self-contained Web applications的概念
2.32001.08J2EE 1.3JSR 53增加了Filter,增加了關(guān)于Session的Listener(如HttpSessionListener)
2.42003.08J2EE 1.4JSR 154沒(méi)增加大的新內(nèi)容,對(duì)不嚴(yán)格的地方加了些校驗(yàn),如:對(duì)web.xml使用XML Schema
2.52005.09Java EE 5JSR 154最低要求JDK 5。注解支持(如@WebService、@WebMethod等,注意不是@WebServlet這種哦)
3.02009.12Java EE 6JSR 315史上最大變革。動(dòng)態(tài)鏈接庫(kù)和插件能力(Spring MVC利用此能力通過(guò)ServletContainerInitializer進(jìn)行全注解驅(qū)動(dòng)開(kāi)發(fā))、模塊化開(kāi)發(fā)、異步Servlet、安全性、新的文件上傳API、支持WebSocket,新的注解(@WebServlet、@WebFilter、@WebListener),可脫離web.xml全注解驅(qū)動(dòng),此版本功能已經(jīng)很完整了,應(yīng)用的主流
3.12013.5Java EE 7JSR 340新增非阻塞式IO。Spring的Web Flux若要運(yùn)行在Servlet容器,至少需要此版本,因?yàn)閺拇税姹酒鸩庞蟹亲钄噍斎胼敵龅闹С?/td>
4.02017.09Java EE 8JSR 369支持Http/2。從而支持服務(wù)器推技術(shù),新的映射發(fā)現(xiàn)接口HttpServletMapping可用來(lái)提高內(nèi)部的運(yùn)行效率
5.02020.11Jakarta EE 9JSR 369同Servlet 4.0(只是命名空間從javax.*變?yōu)榱?code>jakarta.*而已)

Spring Boot相關(guān):

  • 2.0.0.RELEASE版本(2018.05):正式內(nèi)置Servlet 3.1,畢竟Spring Web Flux從此版本開(kāi)始(Spring 5)
  • 2.1.0.RELEASE版本(2018.10):升級(jí)到Servlet 4.x,直到現(xiàn)在(2.6.x)也依舊是4.x版本
  • 2.2.0.RELEASE版本(2019.10):開(kāi)始支持jakarta.servlet這個(gè)GAV,(和javax.servlet)二者并行
  • 2.5.0/2.6.0版本(2021.05):無(wú)變化
  • 3.0.0版本(預(yù)計(jì)2022.12):基于Spring 6.x、Jakarta EE 9,基于GraalVM全面擁抱云原生的新一代框架

說(shuō)明:Spring Boot 2.6和2.7都還會(huì)基于Spring Framework 5.3.x內(nèi)核。Spring Framework 6.0版本在2021年9月正式拉開(kāi)序幕,將基于全新的Jakarta EE 9(命名空間為jakarta.*,不向下兼容)平臺(tái)開(kāi)發(fā),相應(yīng)的Spring Boot 3也會(huì)基于此內(nèi)核

生存現(xiàn)狀

隨著Spring 5的發(fā)布推出WebFlux,Servlet技術(shù)從之前的必選項(xiàng)變?yōu)榭蛇x項(xiàng)。

但考慮到業(yè)務(wù)開(kāi)發(fā)使用WebFlux收益甚微但開(kāi)發(fā)調(diào)試成本均增加,因此實(shí)際情況是基于Servlet的Spring MVC技術(shù)依舊是主流,暫時(shí)地位不可撼動(dòng),依舊非?;钴S。

實(shí)現(xiàn)(框架)

由于Servlet由Web容器負(fù)責(zé)創(chuàng)建并調(diào)用,因此只要實(shí)現(xiàn)了Servlet規(guī)范的Web容器均可作為它的實(shí)現(xiàn)(框架),如Tomcat、Jetty、Undertow、JBoss、Glassfish等。

代碼示例

導(dǎo)入依賴包:

scope一般provided即可,因?yàn)閃eb容器里會(huì)自帶此Jar

Spring Boot場(chǎng)景下無(wú)需顯示導(dǎo)入,因?yàn)門omcat已內(nèi)嵌(相關(guān)API)

 
 
 
 
  1. servlet-api的GAV 

繼承HttpServlet寫一個(gè)用于處理Http請(qǐng)求的Servlet處理器

 
 
 
 
  1. /** 
  2.  * 在此處添加備注信息 
  3.  * 
  4.  * @author YourBatman. Send email to me 
  5.  * @site https://yourbatman.cn 
  6.  * @date 2021/9/12 06:23 
  7.  * @since 0.0.1 
  8.  */ 
  9. @WebServlet(urlPatterns = {"/hello"}) 
  10. public class HelloServlet extends HttpServlet { 
  11.  
  12.     @Override 
  13.     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  14.         resp.getWriter().write("hello servlet..."); 
  15.     } 

IDEA添加(外置)Tomcat 9.x版本,以war包形式部署到Tomcat(小提示: war ),并啟動(dòng)Tomcat

瀏覽器http://localhost:8080/hello即可完成正常訪問(wèn)。

說(shuō)明:自Servlet 3.0之后,web.xml部署描述符并非必須(全注解即可搞定)

工程源代碼:https://github.com/yourbatman/BATutopia-java-ee

JSP

Java Server Page的簡(jiǎn)稱。那么,有了Servlet為何還需要JSP?其實(shí)它倆都屬于動(dòng)態(tài)Web技術(shù),只是Servlet它用于輸出頁(yè)面簡(jiǎn)直太繁瑣了(每一句html都需要用resp.getWriter()逐字逐句的輸出),所以才出現(xiàn)了JSP技術(shù)來(lái)彌補(bǔ)其不足。

它使用JSP標(biāo)簽在HTML網(wǎng)頁(yè)中插入Java代碼。語(yǔ)法格式為:<% Java代碼 %>。它有九大內(nèi)置對(duì)象這么一說(shuō):

 
 
 
 
  1. 1、request:請(qǐng)求對(duì)象。javax.servlet.http.HttpServletRequest 
  2. 2、response:響應(yīng)對(duì)象。javax.servlet.http.HttpServletResponse 
  3. 3、session:會(huì)話對(duì)象。javax.servlet.http.HttpSession 
  4. 4、application:應(yīng)用程序?qū)ο?。javax.servlet.ServletContext 
  5. 5、config:配置對(duì)象。javax.servlet.ServletConfig 
  6. 6、page:頁(yè)面對(duì)象。當(dāng)前jsp程序本身,相當(dāng)于this 
  7. 7、pageContext:頁(yè)面上下文對(duì)象。javax.servlet.jsp.PageContext 
  8. 8、out:輸出流對(duì)象,用于輸出內(nèi)容到瀏覽器。javax.servlet.jsp.jspWriter 
  9. 9、exception:異常對(duì)象,只有在包含isErrorPage=”true”的頁(yè)面中才可以被使用。java.lang.Throwable 

除了Servlet。與JSP 強(qiáng)相關(guān) 的技術(shù)還有EL表達(dá)式和JSP標(biāo)簽(JSTL),下面會(huì)接著介紹。

 
 
 
 
  1.  
  2.  
  3.     javax.servlet.jsp 
  4.     javax.servlet.jsp-api 
  5.     2.3.3 
  6.     provided 
  7.  
  8.  
  9.  
  10.  
  11.     jakarta.servlet.jsp 
  12.     jakarta.servlet.jsp-api 
  13.     3.0.0 
  14.      
  15.     provided 
  16.  

版本歷史

由于JSP的本質(zhì)就是Servlet,它的的版本號(hào)需要與Servlet對(duì)應(yīng)看待。

版本 發(fā)布日期 JSR版本 對(duì)應(yīng)Servlet版本
JSP 1.12000.07JSR 906Servlet 2.2
JSP 1.22002.06JSR 53Servlet 2.3
JSP 2.02003.11JSR 152Servlet 2.4
JSP 2.12005.09JSR 245Servlet 2.5
JSP 2.22009.12JSR 245(升級(jí)版)Servlet 3.0
JSP 2.32013.05JSR 372(升級(jí)版)Servlet 3.1
JSP 3.02020.11----(Jakarta旗下)Servlet 5.x

Spring Boot相關(guān):Spring Boot從1.x版本開(kāi)始就一直沒(méi)有“帶”JSP一起玩,若要Spring Boot支持JSP需要特殊開(kāi)啟。

JSP 2.0是個(gè)重要版本,最重要的特性就是開(kāi)始支持EL表達(dá)式了,可以用它來(lái)訪問(wèn)應(yīng)用程序數(shù)據(jù)。JSP 2.3版本可斷定是最后一個(gè)版本,因?yàn)镴SP已走到盡頭,成為歷史。

生存現(xiàn)狀

JSP誕生之后,程序員寫頁(yè)面寫得確實(shí)很爽了。但是,它帶來(lái)了壞處:很多程序員同學(xué)將業(yè)務(wù)邏輯、頁(yè)面展示邏輯都往JSP塞,耦合在一起,導(dǎo)致JSP扛不住了,更重要的是程序員扛不住了,非常凌亂。

雖然后面出現(xiàn)了EL表達(dá)式和JSTL標(biāo)簽來(lái)幫助程序員不要在JSP里寫Java代碼,但只要不是強(qiáng)制的你能限制住自由的程序員么?然后呢,后來(lái)出現(xiàn)了Freemarker和Velocity這種模板引擎,使得程序員沒(méi)有辦法在頁(yè)面上寫Java代碼了,達(dá)到了分離的效果。

模板引擎出現(xiàn)后,JSP的地位已經(jīng)岌岌可危了。但真正殺死它的還是前端的崛起,從而進(jìn)入前后端完全分離的狀態(tài),至此基本可以宣布JSP(甚至包括模板引擎)的死亡。

所以JSP目前的生存狀態(tài)是:基本死亡狀態(tài)。你看,這不Spring Boot(默認(rèn))都不帶他玩了嘛~

實(shí)現(xiàn)(框架)

與Servlet相同的Web容器。

代碼示例

導(dǎo)包。由于我們不可能直接使用JSP的API,因此99.9999%情況下無(wú)需導(dǎo)包。

 
 
 
 
  1. 無(wú)需導(dǎo)包 

創(chuàng)建webapp內(nèi)容文件夾。這點(diǎn)很重要,因?yàn)槭且獎(jiǎng)?chuàng)建一個(gè)web文件夾,以IDEA為例:在jsp-demo工程下添加web模塊圖片圖片完成后工程目錄結(jié)構(gòu)如下:

完成后工程目錄結(jié)構(gòu)如下:

值得一提的是:web目錄名稱叫什么無(wú)所謂(只是很多喜歡叫webapp、webroot等),重要的是要有這個(gè)小圓點(diǎn)。不乏聽(tīng)見(jiàn)不少小伙伴說(shuō)這個(gè)目錄名必須叫webapp,其實(shí)它名字叫什么、甚至位置放在哪都無(wú)所謂,重要是找得到就行。掌握原理,一通百通。

這里附上HelloJsp的內(nèi)容:

 
 
 
 
  1. /** 
  2.  * 在此處添加備注信息 
  3.  * 
  4.  * @author YourBatman. Send email to me 
  5.  * @site https://yourbatman.cn 
  6.  * @date 2021/9/12 06:26 
  7.  * @since 0.0.1 
  8.  */ 
  9. @WebServlet(urlPatterns = {"/hellojsp"}) 
  10. public class HelloJsp extends HttpServlet { 
  11.  
  12.     @Override 
  13.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
  14.         RequestDispatcher requestDispatcher = request.getRequestDispatcher("hello.jsp"); 
  15.         // 放在WBE-INF下面的.jsp頁(yè)面必須通過(guò)Servlet轉(zhuǎn)發(fā)才能訪問(wèn)到,更加安全 
  16.         // RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/hello.jsp"); 
  17.         requestDispatcher.forward(request, response); 
  18.     } 

以war包形式部署至Tomcat圖片瀏覽器訪問(wèn)下面兩個(gè)路徑均可得到響應(yīng)結(jié)果:

  • http://localhost:8080/hellojsp:請(qǐng)求 -> Servlet轉(zhuǎn)發(fā) -> jsp頁(yè)面(即使jsp頁(yè)面放到WEB-INF目錄下依舊可訪問(wèn))
  • http://localhost:8080/hello.jsp:請(qǐng)求 -> jsp頁(yè)面(此直接方式只能訪問(wèn)非WEB-INF目錄下的jsp文件)

頁(yè)面響應(yīng):

再?gòu)?qiáng)調(diào)一遍:自Servlet 3.0之后,web.xml部署描述符并非必須。即使有jsp頁(yè)面也是一樣~~~

工程源代碼:https://github.com/yourbatman/BATutopia-java-ee

EL表達(dá)式

Expression Language表達(dá)式語(yǔ)言。EL表達(dá)式語(yǔ)言的靈感來(lái)自于ECMAScript和XPath表達(dá)式語(yǔ)言(表達(dá)式語(yǔ)言當(dāng)然還有比較著名的Spring的SpEL,以及OGNL),它提供了在 JSP 中簡(jiǎn)化表達(dá)式的方法,目的是替代掉在Jsp里寫Java代碼,讓Jsp的代碼更加簡(jiǎn)化。

基本語(yǔ)法為:${EL表達(dá)式 },只能讀取數(shù)據(jù)不能設(shè)置數(shù)據(jù)(設(shè)置數(shù)據(jù)用JSP內(nèi)或者Servlet里的Java代碼均可)

請(qǐng)務(wù)必注意,基本語(yǔ)法中右邊的}的前面有個(gè)空格,使用時(shí)請(qǐng)務(wù)必注意

在EL中有四大域?qū)ο蠛?1大內(nèi)置對(duì)象這么一說(shuō):

  • 請(qǐng)求參數(shù)
 
 
 
 
  1. 1、param 包含所有的參數(shù)的Map,可以獲取參數(shù)返回String。其底層實(shí)際調(diào)用request.getParameter() 
  2.  - name=${param.name } 
  3. 2、paramValues 包含所有參數(shù)的Map,可以獲取參數(shù)的數(shù)組返回String[]。其底層實(shí)際調(diào)用request.getParameterValues() 
  4.  - hobby[0]=${paramValues.hobby[0] } 
  • 頭信息
 
 
 
 
  1. 3、header 包含所有的頭信息的Map,可以獲取頭信息返回String。 
  2.  - ${header.Connection } 
  3. 4、headerValues 包含所有的頭信息的Map,可以獲取頭信息數(shù)組返回String[]。 
  4.  - ${headerValues["user-agent"][0] } 
  • Cookie
 
 
 
 
  1. 5、cookie包含所有cookie的Map,key為Cookie的name屬性值 
  2.  - ${cookie.JSESSIONID.name } 
  • 初始化參數(shù)
 
 
 
 
  1. 6、iniParam 包含所有的初始化參數(shù)(一般配在web.xml里)的Map,可以獲取初始化的參數(shù) 
  2.  - ${initParam.username} ${initParam.password} 
  • 四大作用域(重點(diǎn))
 
 
 
 
  1. 7、pageScope 包含page作用域內(nèi)的Map 
  2.  - ${pageScope.name } 
  3. 8、requestScope 包含request作用域內(nèi)的Map 
  4.  - ${requestScope.name } 
  5. 9、 包含session作用域內(nèi)的Map 
  6.  - ${sessionScope.name } 
  7. 10、applicationScope 包含application作用域內(nèi)的Map 
  8.  - ${applicationScope.name } 
  • 頁(yè)面上下文
 
 
 
 
  1. 11、pageContext 包含頁(yè)面內(nèi)的變量的Map,可獲取JSP中的九大內(nèi)置對(duì)象 
  2.  - ${pageContext.request.scheme } 
  3.  - ${pageContext.session.id} 
 
 
 
 
  1.  
  2.  
  3.     javax.el 
  4.     javax.el-api 
  5.     3.0.0 
  6.  
  7.  
  8.  
  9.  
  10.     jakarta.el 
  11.     jakarta.el-api 
  12.     4.0.0 
  13.      
  14.  
  15.  
  16. 除此之外,還可以通過(guò)Tomcat的GAV直接導(dǎo)入,版本號(hào)同Tomcat 
  17.  
  18.     org.apache.tomcat 
  19.     tomcat-el-api 
  20.     Tomcat版本號(hào)  
  21.  
  22. 嵌入式Tomcat提供的實(shí)現(xiàn) 
  23.  
  24.     org.apache.tomcat.embed 
  25.     tomcat-embed-el 
  26.     Tomcat版本號(hào)  
  27.  
  28.  
  29. 另外,還有二合一的GAV:3.x版本的API和impl實(shí)現(xiàn)都在一個(gè)jar里。 
  30. 4.x使用jakarta.*命名空間,并且API分離(依賴于)jakarta.el-api 
  31.  
  32.     org.glassfish 
  33.     jakarta.el 
  34.     4.0.2 
  35.      
  36.  

值得注意的是,EL并非Web獨(dú)享而是可獨(dú)立使用,因此它的scope用默認(rèn)的即可。另外,這只是API,并非Impl實(shí)現(xiàn),是不能直接運(yùn)行的,否則會(huì)遇到類似如下異常:

 
 
 
 
  1. Caused by: javax.el.ELException: Provider com.sun.el.ExpressionFactoryImpl not found 
  2.  at javax.el.FactoryFinder.newInstance(FactoryFinder.java:101) 
  3.  ... 

版本歷史

EL從JSP 2.0版本開(kāi)始引入,用于在JSP頁(yè)面獲取數(shù)據(jù)的簡(jiǎn)單方式。因此它是隨著JSP的發(fā)展而出現(xiàn)的,只是可獨(dú)立使用而已。

版本 發(fā)布日期 JSR版本 對(duì)應(yīng)JSP版本 對(duì)應(yīng)Servlet版本
EL 2.02003.11JSR 152JSP 2.0Servlet 2.4
EL 2.22009.12JSR 245JSP 2.2Servlet 2.5
EL 3.02013.05JSR 341JSP 2.3Servlet 3.1
EL 4.02020.10納入JakartaJSP 3.0Servlet 5.0

EL表達(dá)式3.0于2013年4月份發(fā)布(可認(rèn)為是最后一次功能升級(jí)),它的新特性包括:字符串拼接操作符、賦值(以前只能讀取,現(xiàn)在可以賦值啦)、分號(hào)操作符、對(duì)象方法調(diào)用(以前只能用JavaBean屬性導(dǎo)航)、Lambda表達(dá)式、靜態(tài)字段/方法調(diào)用、構(gòu)造器調(diào)用、Java8集合操作。具體就不一一舉例了,詳細(xì)情況可閱讀我收錄的JSR文檔。

生存現(xiàn)狀

隨著JSP的消亡,EL的存在感越來(lái)越弱。

好在它可以作為單獨(dú)的表達(dá)式語(yǔ)言使用,有Hibernate Validator對(duì)它是強(qiáng)依賴,所以生命力還行。但由于Hibernate Validator里使用得簡(jiǎn)單,所以EL并沒(méi)有必要再更新(動(dòng)力不足)。

實(shí)現(xiàn)(框架)

EL大部分情況下伴隨著JSP一起使用,所以交由Web容器去解析實(shí)現(xiàn)。

另外,EL作為一種表達(dá)式語(yǔ)言,也可以作為”工具“供以使用,比如著名的Hibernate Validator內(nèi)部就依賴于EL表達(dá)式語(yǔ)言來(lái)書寫校驗(yàn)規(guī)則(所以它在編譯期就強(qiáng)依賴于EL的API)。

代碼示例

在JSP中使用EL是由org.apache.tomcat:tomcat-jasper-el或者org.apache.tomcat.embed:tomcat-embed-jasper完成和JSP的整合,以及解析支持的。在JSP頁(yè)面里使用方式由于已經(jīng)過(guò)時(shí)(主要是使用示例一搜一大把),這里為了節(jié)約篇幅,就略了哈。

如果把EL當(dāng)做工具使用的話(比如Hibernate Validator用來(lái)錯(cuò)誤消息里插值用),需要了解一些API和常見(jiàn)用法,演示一下:

導(dǎo)包:

 
 
 
 
  1. 上面的GAV隨便選一個(gè)(記得太impl實(shí)現(xiàn),推薦org.glassfish:jakarta.el) 

直接使用API書寫Demo

 
 
 
 
  1. /** 
  2.  * 在此處添加備注信息 
  3.  * 
  4.  * @author YourBatman. Send email to me 
  5.  * @site https://yourbatman.cn 
  6.  * @date 2021/9/12 10:12 
  7.  * @since 0.0.1 
  8.  */ 
  9. public class ElDemo { 
  10.  
  11.     public static void main(String[] args) { 
  12.         ExpressionFactory factory = ELManager.getExpressionFactory(); 
  13.         StandardELContext elContext = new StandardELContext(factory); 
  14.  
  15.         // 將instance轉(zhuǎn)為對(duì)應(yīng)類型 
  16.         ValueExpression valueExpression = factory.createValueExpression("18", Integer.class); 
  17.         System.out.println(valueExpression.getValue(elContext)); 
  18.  
  19.         // 計(jì)算表達(dá)式的值 
  20.         valueExpression = factory.createValueExpression(elContext, "${1+1}", Integer.class); 
  21.         System.out.println(valueExpression.getValue(elContext)); 
  22.  
  23.         // 方法調(diào)用 
  24.         // MethodExpression methodExpression = factory.createMethodExpression(elContext, "${Math.addExact()}", Integer.class, new Class[]{Integer.class, Integer.class}); 
  25.         // System.out.println(methodExpression.invoke(elContext, new Object[]{1, 2})); 
  26.     } 
  27.  
  28.  
  29. 運(yùn)行,結(jié)果輸出: 
  30. 18 

工程源代碼:https://github.com/yourbatman/BATutopia-java-ee

總結(jié)

現(xiàn)在越來(lái)越卷的IT行業(yè),衡量一個(gè)求職者的專業(yè)能力,深度往往比廣度更為重要。

正所謂這輩子聽(tīng)過(guò)很多大道理,卻依舊過(guò)不好這一生;技術(shù)也一樣,聽(tīng)過(guò)/知道過(guò)/使用過(guò)很多技術(shù),但依舊寫不出好的代碼。究其原因,就是理解不深刻。 

自上而下的用,自底向上的學(xué),這是我個(gè)人一直秉承的一個(gè)觀念。知道一門技術(shù)、使用一門技術(shù)一般幾個(gè)小時(shí)or幾天就能大概搞定(畢竟如果一門技術(shù)入門很難的話也幾乎不太可能大眾化的流行起來(lái)),而理解一門技術(shù)的單位可能就是月、甚至是年了,這需要靜下心來(lái)學(xué)習(xí)和研究。


網(wǎng)頁(yè)名稱:版本歷史&代碼示例之Servelt、JSP、EL表達(dá)式
本文URL:http://m.5511xx.com/article/cdodihh.html