2020年了,還須要學JSP嗎?我相信如今仍是在大學的同窗確定會有這個疑問。html
其實我在18年的時候已經見過相似的問題了「JSP還應該學習嗎」。我在18年發了幾篇JSP的文章,已經有很多的開發者評論『這不是上個世紀的東西了嗎』『夢迴幾年前』『這麼老的的東西,怎麼還有人學』前端
如今問題來了,JSP放在2020年,是真的老了嗎?對,是真的老了java
如今問題又來了,爲何在幾年前已經被定義『老』的技術,到2020年了仍是有熱度,每一年仍是有人在問:『還須要學習JSP嗎』。我認爲理由也很簡單:JSP在以前用的是真的多!git
在我初學Java的時候,就常常聽到:JSP和PHP是可以寫動態網頁的---《個人老師》。github
當咱們去找相關的學習資料時,發現處處都是JSP的身影,會給我一種感受:好像不懂JSP就壓根無法繼續往下學習同樣。express
若是你是新手,若是你還沒學習JSP,我建議仍是能夠瞭解一下,不須要深刻去學習JSP的各類內容,但能夠了解一下。至少別人提及JSP的時候,你能知道什麼是JSP,能看懂JSP的代碼。apache
額外說一句:你去到公司,可能還能看到JSP的代碼。雖然JSP是『老東西』,但咱們去到公司可能就是維護老的項目。JSP可能不用你本身去寫,但至少能看得懂,對不對。後端
問題又來了,那JSP若是是『老東西』,那被什麼替代了呢?要麼就是用常見的模板引擎『freemarker』『Thymeleaf』『Velocity』,用法其實跟『JSP』差不太多,只是它們的性能會更好。要麼先後端分離,後端只須要返回JSON給前端,頁面徹底不須要後端管。瀏覽器
說了這麼多,我想說的是:「JSP仍是有必要了解一下,不須要花不少時間,知道便可,這篇文章我就能帶你認識JSP」tomcat
JSP全名爲Java Server Pages,java服務器頁面。JSP是一種基於文本的程序,其特色就是HTML和Java代碼共同存在!JSP是爲了簡化Servlet的工做出現的替代品,Servlet輸出HTML很是困難,JSP就是替代Servlet輸出HTML的。
在Tomcat博客中我提到過:Tomcat訪問任何的資源都是在訪問Servlet!,固然了,JSP也不例外!JSP自己就是一種Servlet。爲何我說JSP自己就是一種Servlet呢?其實JSP在第一次被訪問的時候會被編譯爲HttpJspPage類(該類是HttpServlet的一個子類)
好比我隨便找一個JSP,編譯後的JSP長這個樣:
package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import java.util.Date; public final class _1_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory(); private static java.util.List<String> _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.List<String> getDependants() { return _jspx_dependants; } public void _jspInit() { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } public void _jspDestroy() { } public void _jspService(final HttpServletRequest request, final HttpServletResponse response) throws java.io.IOException, ServletException { final PageContext pageContext; HttpSession session = null; final ServletContext application; final ServletConfig config; JspWriter out = null; final Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try { response.setContentType("text/html;charset=UTF-8"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("\r\n"); out.write("\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write(" <title>簡單使用JSP</title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); String s = "HelloWorda"; out.println(s); out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>\r\n"); } catch (Throwable t) { if (!(t instanceof SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { out.clearBuffer(); } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } }
編譯過程是這樣子的:瀏覽器第一次請求1.jsp時,Tomcat會將1.jsp轉化成1_jsp.java這麼一個類,並將該文件編譯成class文件。編譯完畢後再運行class文件來響應瀏覽器的請求。
之後訪問1.jsp就再也不從新編譯jsp文件了,直接調用class文件來響應瀏覽器。固然了,若是Tomcat檢測到JSP頁面改動了的話,會從新編譯的。
既然JSP是一個Servlet,那JSP頁面中的HTML排版標籤是怎麼樣被髮送到瀏覽器的?咱們來看下上面1_jsp.java的源碼就知道了。原來就是用write()出去的罷了。說到底,JSP就是封裝了Servlet的java程序罷了。
out.write("\r\n"); out.write("\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write(" <title>簡單使用JSP</title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n");
有人可能也會問:JSP頁面的代碼服務器是怎麼執行的?再看回1_jsp.java文件,java代碼就直接在類中的service()中。
String s = "HelloWorda"; out.println(s);
JSP內置了9個對象!內置對象有:out、session、response、request、config、page、application、pageContext、exception。
重要要記住的是:JSP的本質其實就是Servlet。只是JSP當初設計的目的是爲了簡化Servlet輸出HTML代碼。
重複一句:JSP的本質其實就是Servlet。只是JSP當初設計的目的是爲了簡化Servlet輸出HTML代碼。
咱們的Java代碼仍是寫在Servlet上的,不會寫在JSP上。在知乎曾經看到一個問題:「如何使用JSP鏈接JDBC」。顯然,咱們能夠這樣作,可是不必。
JSP看起來就像是一個HTML,再往裏邊增長大量的Java代碼,這是不正常,不容易閱讀的。
因此,咱們通常的模式是:在Servlet處理好的數據,轉發到JSP,JSP只管對小部分的數據處理以及JSP自己寫好的頁面。
例如,下面的Servlet處理好表單的數據,放在request對象,轉發到JSP
//驗證表單的數據是否合法,若是不合法就跳轉回去註冊的頁面 if(formBean.validate()==false){ //在跳轉以前,把formbean對象傳遞給註冊頁面 request.setAttribute("formbean", formBean); request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response); return; }
JSP拿到Servlet處理好的數據,作顯示使用:
JSP咱們要學的其實兩塊就夠了:JSTL和EL表達式
表達式語言(Expression Language,EL),EL表達式是用${}
括起來的腳本,用來更方便的讀取對象!EL表達式主要用來讀取數據,進行內容的顯示!
爲何要使用EL表達式?咱們先來看一下沒有EL表達式是怎麼樣讀取對象數據的吧!在1.jsp中設置了Session屬性
<%@ page language="java" contentType="text/html" pageEncoding="UTF-8"%> <html> <head> <title>向session設置一個屬性</title> </head> <body> <% //向session設置一個屬性 session.setAttribute("name", "aaa"); System.out.println("向session設置了一個屬性"); %> </body> </html>
在2.jsp中獲取Session設置的屬性
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title></title> </head> <body> <% String value = (String) session.getAttribute("name"); out.write(value); %> </body> </html>
效果:
上面看起來,也沒有多複雜呀,那咱們試試EL表達式的!
在2.jsp中讀取Session設置的屬性
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title></title> </head> <body> ${name} </body> </html>
只用了簡簡單單的幾個字母就能輸出Session設置的屬性了!而且輸出在瀏覽器上!
使用EL表達式能夠方便地讀取對象中的屬性、提交的參數、JavaBean、甚至集合!
JSTL全稱爲 JSP Standard Tag Library 即JSP標準標籤庫。JSTL做爲最基本的標籤庫,提供了一系列的JSP標籤,實現了基本的功能:集合的遍歷、數據的輸出、字符串的處理、數據的格式化等等!
爲何要使用JSTL?
EL表達式不夠完美,須要JSTL的支持!在JSP中,咱們前面已經用到了EL表達式,體會到了EL表達式的強大功能:使用EL表達式能夠很方便地引用一些JavaBean以及其屬性,不會拋出NullPointerException之類的錯誤!可是,EL表達式很是有限,它不能遍歷集合,作邏輯的控制。這時,就須要JSTL的支持了!
Scriptlet的可讀性,維護性,重用性都十分差!JSTL與HTML代碼十分相似,遵循着XML標籤語法,使用JSTL讓JSP頁面顯得整潔,可讀性很是好,重用性很是高,能夠完成複雜的功能!
以前咱們在使用EL表達式獲取到集合的數據,遍歷集合都是用scriptlet代碼循環,如今咱們學了forEach標籤就能夠捨棄scriptlet代碼了。
向Session中設置屬性,屬性的類型是List集合
<% List list = new ArrayList<>(); list.add("zhongfucheng"); list.add("ouzicheng"); list.add("xiaoming"); session.setAttribute("list", list); %>
遍歷session屬性中的List集合,items:即將要迭代的集合。var:當前迭代到的元素
<c:forEach var="list" items="${list}" > ${list}<br> </c:forEach>
效果:
如今已經工做有一段時間了,爲何還來寫JSP
呢,緣由有如下幾個:
read.me
會常常更換。如今的GitHub導航也不合我心意了(太長了),而且早期的文章,說實話排版也不太行,我決定從新搞一波。基於上面的緣由,我決定把個人系列文章彙總成一個PDF/HTML/WORD
文檔。說實話,打造這麼一個文檔花了我很多的時間。爲了防止白嫖,關注個人公衆號回覆「888」便可獲取。
PDF的內容很是很是長,乾貨很是很是的硬,有興趣的同窗能夠瀏覽一波。記住:JSP咱們只須要了解便可,不須要深刻去學習每一個知識點,由於在現實開發中極可能用不上。
文檔的內容均爲手打,有任何的不懂均可以直接來問我(公衆號有個人聯繫方式)。
上一期的「排序和數據結構」的PDF在公衆號反響仍是挺不錯的,目標是180個在看,超出了預期,因此我提前更新了。
若是此次點贊超過180,那下週再肝一個系列出來。想要看什麼,能夠留言告訴我
若是你們想要實時關注我更新的文章以及分享的乾貨的話,微信搜索Java3y。
PDF文檔的內容均爲手打,有任何的不懂均可以直接來問我(公衆號有個人聯繫方式)。