整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          曾經(jīng)風(fēng)光無限的 JSP,為什么現(xiàn)在很少有人使用了?

          源 | 愚公要移山(ID:fdd_sxu_nwpu)

          jsp技術(shù)作為曾經(jīng)一度火爆的技術(shù),在最近幾年確實使用率越來越低了,這篇文章帶你一塊探究一下jsp的從生到死。

          jsp技術(shù)的誕生

          在很久很久以前,那時候我們的開發(fā)都是通過servlet來完成的,這個servlet是什么呢?我們先來認(rèn)識一下:

          servlet用Java語言編寫的服務(wù)器端程序。主要功能是和瀏覽器進行交互,生成頁面展示。

          長下面這個樣子:

          public class HelloWorld extends HttpServlet {  public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {  response.setContentType("text/html");  PrintWriter out = response.getWriter;  out.println("<html>");  out.println("<head>");  out.println("<title>Hello World</title>");  out.println("</head>");  out.println("<body>");  out.println("<h1>Hello World!</h1>");  out.println("</body>");  out.println("</html>");  }  }

          我們可以看到前端所展示的頁面,需要我們servlet去一個標(biāo)簽一個標(biāo)簽去生成,如果一個頁面超級復(fù)雜,動不動幾千行代碼,那這個servlet效率也就太低了。而且整個servlet代碼也會十分臃腫而且可讀性非常差。

          這時候怎么辦呢?sun公司很早就意識到了這個問題,于是便倡導(dǎo)很多公司一塊來創(chuàng)建了一種能夠動態(tài)生成html的新技術(shù),不久之后jsp便誕生了。有效率的解決了上面servlet所出現(xiàn)的問題。

          jsp的發(fā)展

          既然jsp技術(shù)能夠解決剛剛servlet代碼里面所出現(xiàn)的技術(shù),我們來看一下是如何解決的:在這里我們舉一個小例子,就是前端jsp向服務(wù)器servlet發(fā)送請求圖書頁面的功能。

          首先我們看一下servlet:

          public class List_book extends HttpServlet {  public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {  //聲明一個ArrayList.用來存放Book類中的數(shù)據(jù)  ArrayList<Book> list = new ArrayList<Book>;  for(int i=0;i<10;i++){ Book book = new Book;  book.setName(res.getString("name"+i));  book.setAuthor(res.getString("author"+i));  list.add(book);  } //將list數(shù)據(jù)發(fā)送到.jap文件中  request.getRequestDispatcher("ListBook.jsp").forward(request, response);  } }

          我們會發(fā)現(xiàn),現(xiàn)在的servlet沒有一點html代碼了。我們只需要把數(shù)據(jù)交給jsp。此時我們的頁面展示就交給jsp來做了。現(xiàn)在我們來看一下jsp長什么樣子:

          <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%String path = request.getContextPath;%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head>  <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="description" content="This is my page"> <script></script>  </head>  <body>  <% ArrayList list = (ArrayList) request.getAttribute("list"); %>  <h2 align = "center">圖書列表</h2>  <table border = 1px align = "center">  <tr><th>圖書名稱</th><th>圖書作者</th></tr>  <!-- 繼續(xù)使用jsp語句 循環(huán)放入存放于list中的Book實體類中的數(shù)據(jù) -->  <%  for(int i = 0;i<list.size;i++){  Book book =(Book)  list.get(i);%>  <tr><th><%=book.getName %></th><th><%=book.getAuthor%></th><tr> } %> </table>  </body> </html>

          這就是jsp,我們可以在html頁面中寫一些java代碼。對于我們程序員來說,在開發(fā)當(dāng)中靜態(tài)的頁面我們只需要用html和css寫一些標(biāo)簽來展示即可,對于那些動態(tài)的部分我們就可以使用java代碼。

          那么jsp和servlet是不是就是這種協(xié)作的關(guān)系,本質(zhì)上有什么區(qū)別呢?

          其實jsp只是servlet的一種特殊形式,每一個jsp頁面就是一個servlet實例,通俗一點的話來說:jsp就是servlet,只不過servlet把一些業(yè)務(wù)功能剝離開來交給了或者是形成了jsp。明白了吧。在我們的項目編譯的時候就是把jsp編譯成了servlet。

          你們會發(fā)現(xiàn),這樣做其實挺好的,市場也驗證了一切,很快jsp技術(shù)流行開來,可是隨著時間的流逝,業(yè)務(wù)越來越復(fù)雜,jsp也開始跟不上時代了。

          jsp的危機

          我們先看一個對話場景:

          java程序員:終于寫完了功能,是時候在界面上展示了。

          前端程序員:你功能寫完了,我沒有數(shù)據(jù),在頁面什么沒法展示呀

          java程序員:數(shù)據(jù)我寫好了,你在jsp中調(diào)用XX方法就能獲取了,

          前端程序員:我已經(jīng)在jsp中寫好了這個方法,你為什么自己寫了?

          于是乎,無窮無盡的爭吵還在繼續(xù)當(dāng)中。

          這就是jsp的弊端,為什么呢?我們可以來總結(jié)一下:

          (1)動態(tài)和靜態(tài)資源放在一起,一旦服務(wù)器出現(xiàn)狀況,前后臺一起玩完,用戶體驗極差。

          (2)一旦jsp出現(xiàn)了問題,就需要前端后端發(fā)開人員一塊來分析解決,效率低。

          (3)jsp無法使用nginx等。

          (4)jsp頁面復(fù)雜,難以修改。

          (5)第一次加載jsp需要編譯成servlet,時間久,而且業(yè)務(wù)量大的時候,jsp負擔(dān)太大。

          (6)jsp對于開發(fā)人員簡直就是一個揮之不去的痛,太難了?。?!

          鑒于以上缺點,于是另外一套機制橫空出世了,這就是前后端分離。什么是前后端分離呢?

          前后端分離其實就是后端工程師只關(guān)注于后端頁面的開發(fā),不再處理前端問題。前端工程師只關(guān)注于自己的頁面開發(fā)。需要數(shù)據(jù)交互的時候,兩者會有一份接口文檔。

          就這樣這種思想架構(gòu)很快的流行開來,這也就是為什么jsp落寞的真正原因。從此java從jsp轉(zhuǎn)向了restful結(jié)構(gòu),springMCV也開始流行開來,并逐漸占領(lǐng)了市場。前后端分離有什么優(yōu)點呢?我們來總結(jié)一下:

          (1)動態(tài)和靜態(tài)資源分開存儲。

          (2)出現(xiàn)bug能很快定位是前端還是后端。

          (3)支持nginx。在高并發(fā)狀態(tài)下極其優(yōu)秀。

          (4)直接請求頁面,不用編譯,速度效率都提上來了。

          (5)從此前端和后端是相親相愛的一家人了?。。?!

          jsp的落幕

          又隨著時間的推移,jsp的時代基本上一去不復(fù)返了,因為我們又走入了移動互聯(lián)時代,這時候的客戶端可不是前端頁面了,還包括手機、汽車、電視等等各種設(shè)備,這種情況下,前后端必須要分離了。jsp基本上徹底告別了它的舞臺。

          隨著容器技術(shù)(docker、k8s)以及微服務(wù)架構(gòu)逐步成熟和發(fā)展,這種強調(diào)后端分離思想讓jsp這個陪伴我近10年的頁面渲染技術(shù)宣告落幕了,有點傷感。。。

          jsp的痛有幾個人明白

          1、無法做到動靜分離

          傳統(tǒng)java程序通過war包形式部署到tomcat,除了java代碼和jsp頁面,還包括css、js、圖片等靜態(tài)資源,一旦其中的某個jsp頁面出問題,會導(dǎo)致部分功能不可用,甚至服務(wù)器響應(yīng)阻塞,無法對外提供服務(wù)。

          2、分工協(xié)調(diào)性差

          jsp本質(zhì)上是一個java類,所以早期java開發(fā)人員是前后端開發(fā)任務(wù)全負責(zé),而UI設(shè)計師把設(shè)計好的html頁面給開發(fā)人員集成,這個需要雙方共同協(xié)調(diào)完成,效率低下,很難完成需求快速更新迭代,持續(xù)交付。

          3、并發(fā)、吞吐量差

          由于jsp本質(zhì)是java類,只能放在web服務(wù)器(如tomcat),所以jsp不能部署到并發(fā)性能更好的nginx或者apache下,這是很多人詬病java web性能不好的原因之一。

          4、擴展性差

          jstl內(nèi)置的一些tag標(biāo)簽耦合java代碼(類似于react中的component組件),很難做到只修改頁面而不用修改java代碼,擴展性很差。

          5、頁面加載慢(同步機制)

          如果一個頁面承載的內(nèi)容很多(如表單、表格、詳情),會導(dǎo)致頁面加載很慢。究其原因是jsp內(nèi)在特性決定的。

          jsp初始化流程

          首先,jsp頁面會初始化為servlet的class文件

          其次,在servlet代碼中解析jsp tag標(biāo)簽,轉(zhuǎn)換成html網(wǎng)頁標(biāo)簽

          最后,以流的方式輸出html網(wǎng)頁

          這里有個要命的問題,從jsp轉(zhuǎn)換成html到瀏覽器渲染是一個同步過程。也就是說,如果數(shù)據(jù)加載很慢,會導(dǎo)致整個頁面出不來。

          前后端分離思想

          1、動靜分離,前端軟負載架構(gòu)

          后端代碼(如java)和前端(html、js、css、圖片等)分離,單獨部署。

          前端程序強調(diào)靜態(tài)資源,會單獨部署到抗壓能力更強的nginx下。而后端程序由于剝離了頁面、js、css、圖片,以接口形式對外提供服務(wù),

          服務(wù)能力下沉(基礎(chǔ)平臺能力,sass服務(wù)化能力)。

          2、分工明確

          3、異步加載機制

          如果頁面需要多次ajax調(diào)用,不需要同步進行,異步加載實現(xiàn)局部刷新。

          4、組件化

          以react、vue、angular為代表前端框架,提出組件化、框架化、復(fù)用性等工程化編程,使的前端也可以像后端那樣提供可復(fù)用性、可擴展性、高可用性的前端程序。

          小結(jié)

          筆者認(rèn)為,前后端分離思想是一種趨勢,更深層次是技術(shù)更新很快,我們要與時俱進,時刻更新自己的知識庫。當(dāng)然對于之前不了解jsp的同學(xué)還是要去學(xué)習(xí)下,畢竟很多技術(shù)發(fā)展是有繼承性的。

          最后

          如果覺得本文對您有幫助的話,記得關(guān)注、轉(zhuǎn)發(fā)哦,我會為大家持續(xù)提供原創(chuàng)干貨。需要資料,請關(guān)注、轉(zhuǎn)發(fā),私信“資料”面試+微服務(wù)+springboot資料免費贈送。

          言:

          為了后續(xù)的代碼審計一些常用的框架和技術(shù)都是有必要了解一下,在此重拾Spring Boot等開發(fā)知識內(nèi)容。

          1|20x01 Thymeleaf簡介


          Thymeleaf是一個現(xiàn)代的服務(wù)器端Java模板引擎的web和獨立的環(huán)境,能夠處理HTML, XML, JavaScript, CSS,甚至純文本。

          Thymeleaf的主要目標(biāo)是提供一種優(yōu)雅的和高度可維護的方式來創(chuàng)建模板。為了實現(xiàn)這一點,它構(gòu)建在自然模板的概念上,以不影響模板作為設(shè)計原型使用的方式將其邏輯注入模板文件。這改進了設(shè)計的交流,并在設(shè)計和開發(fā)團隊之間架起了橋梁。

          Thymeleaf的設(shè)計從一開始就考慮了Web標(biāo)準(zhǔn),尤其是HTML5

          Thymeleaf是一個非常可擴展的模板引擎(事實上它可以被稱為模板引擎框架),它允許你定義和自定義的方式,你的模板將被處理到一個精細的細節(jié)級別。

          將一些邏輯應(yīng)用到標(biāo)記工件(標(biāo)記、一些文本、注釋,如果模板不是標(biāo)記,則僅僅是占位符)的對象稱為處理程序,這些處理程序的集合—加上一些額外的工件—通常是方言的組成部分。Thymeleaf的核心庫提供了一種稱為標(biāo)準(zhǔn)方言的方言,這對大多數(shù)用戶來說應(yīng)該足夠了。

          1|30x02 Thymeleaf 基礎(chǔ)配置


          這里主要以Srping Boot為主

          <!--引入thymeleaf依賴-->
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-thymeleaf</artifactId>
                  </dependency>
          

          在項目的resources\templates目錄下創(chuàng)建HTML文件,這里注意導(dǎo)入thymeleaf的命名空間,否則無法進行模板的渲染。

          <!doctype html>
          
          <!--注意:引入thymeleaf的名稱空間-->
          <html lang="en" xmlns:th="http://www.thymeleaf.org">
          <head>
              <meta charset="UTF-8">
              <meta name="viewport"
                    content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
              <meta http-equiv="X-UA-Compatible" content="ie=edge">
              <title>Document</title>
          </head>
          <body>
              <p th:text="'hello SpringBoot'">hello thymeleaf</p>
          </body>
          </html>
          

          編寫Controller

          import org.springframework.stereotype.Controller;
          import org.springframework.web.bind.annotation.GetMapping;
          
          @Controller
          public class IndexController {
          
              @GetMapping("home")
              public String index() {
                  return "index";
              }
          }
          
          

          這里的注解需要使用@Controller,不能使用@RestController注解,否則會報錯.

          1. 如果只是使用@RestController注解Controller,則Controller中的方法無法返回jsp頁面,或者html,配置的視圖解析器 InternalResourceViewResolver不起作用,返回的內(nèi)容就是Return 里的內(nèi)容。
          2. 如果需要返回到指定頁面,則需要用 @Controller配合視圖解析器InternalResourceViewResolver才行。
            如果需要返回JSON,XML或自定義mediaType內(nèi)容到頁面,則需要在對應(yīng)的方法上加上@ResponseBody注解。

          1|40x03 Thymeleaf 語法


          類型

          • 1.變量表達式
          • 2.選擇或星號表達式
          • 3.文字國際化表達式
          • 4.URL表達式

          ${...}變量表達式

          <span th:text="${book.author.name}">  
          <li th:each="book : ${books}">  
          

          @{...} 鏈接表達式

           @{/order/list} 
           @{/order/details(id=${orderId})}  
          
          或者是
              
          <form th:action="@{/createOrder}">  
          <a href="main.html" th:href="@{/main}">
          

          #{...} 消息表達式

          #{main.title}  
          #{message.entrycreated(${entryId})}  
          

          *{...} 選擇變量表達式

          <div th:object="${book}">  
          ...  
          <span th:text="*{title}">...</span>  
          ...  
          </div> 
          

          常用th標(biāo)簽

          th標(biāo)簽屬性

          1)th:text:文本替換;

          2)th:utext:支持html的文本替換。

          3)th:value:屬性賦值

          4)th:each:遍歷循環(huán)元素

          5)th:if:判斷條件,類似的還有th:unless,th:switch,th:case

          6)th:insert:代碼塊引入,類似的還有th:replace,th:include,常用于公共代碼塊提取的場景

          7)th:fragment:定義代碼塊,方便被th:insert引用

          8)th:object:聲明變量,一般和*{}一起配合使用,達到偷懶的效果。

          9)th:attr:設(shè)置標(biāo)簽屬性,多個屬性可以用逗號分隔

          1|50x04 結(jié)尾

          內(nèi)容比較簡單,主要作為記錄。


          主站蜘蛛池模板: 国产成人精品一区二三区在线观看 | 无码国产精品一区二区免费式芒果| 亚洲色无码一区二区三区| 激情内射亚州一区二区三区爱妻| 国产亚洲综合一区二区三区 | 国产伦精品一区二区三区精品| 香蕉久久av一区二区三区| 国产成人综合精品一区| 国产精品一区二区毛卡片| 水蜜桃av无码一区二区| 中文字幕VA一区二区三区| 亚洲一区无码精品色| 无码人妻精品一区二区蜜桃AV| 午夜在线视频一区二区三区| 欧美日本精品一区二区三区 | 国产成人午夜精品一区二区三区| 国产成人一区二区三区视频免费| 中文字幕不卡一区| 日韩AV无码一区二区三区不卡毛片| 无码人妻精品一区二区三区99不卡| 99偷拍视频精品一区二区| 亚洲欧美日韩一区二区三区在线| AV鲁丝一区鲁丝二区鲁丝三区| 精品国产伦一区二区三区在线观看 | 福利在线一区二区| 中文字幕色AV一区二区三区| 波多野结衣一区二区三区aV高清| 日韩一区二区在线观看| 一区二区三区福利视频免费观看| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 久久一区不卡中文字幕| 色偷偷一区二区无码视频| 国产成人一区二区三区高清| av一区二区三区人妻少妇| 国产一区二区三区不卡在线看| 天码av无码一区二区三区四区| 波多野结衣一区在线观看| 中文字幕一区二区三| 性色A码一区二区三区天美传媒 | 成人精品视频一区二区三区不卡| 国产精品小黄鸭一区二区三区 |