天天看點

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

前言

2020年了,還需要學JSP嗎?我相信現在還是在大學的同學肯定會有這個疑問。

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜
循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

其實我在18年的時候已經見過類似的問題了「JSP還應該學習嗎」。我在18年發了幾篇JSP的文章,已經有不少的開發者評論『這不是上個世紀的東西了嗎』『夢回幾年前』『這麼老的的東西,怎麼還有人學』

現在問題來了,JSP放在2020年,是真的老了嗎?對,是真的老了

現在問題又來了,為什麼在幾年前已經被定義『老』的技術,到2020年了還是有熱度,每年還是有人在問:『還需要學習JSP嗎』。我認為理由也很簡單:JSP在之前用的是真的多!

在我初學Java的時候,就經常聽到:JSP和PHP是能夠寫動态網頁的—《我的老師》。

當我們去找相關的學習資料時,發現到處都是JSP的身影,會給我一種感覺:好像不懂JSP就壓根沒法繼續往下學習一樣。

如果你是新手,如果你還沒學習JSP,我建議還是可以了解一下,不需要深入去學習JSP的各種内容,但可以了解一下。至少别人說起JSP的時候,你能知道什麼是JSP,能看懂JSP的代碼。

額外說一句:你去到公司,可能還能看到JSP的代碼。雖然JSP是『老東西』,但我們去到公司可能就是維護老的項目。JSP可能不用你自己去寫,但至少能看得懂,對不對。

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜
循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

問題又來了,那JSP如果是『老東西』,那被什麼替代了呢?要麼就是用常見的模闆引擎『freemarker』『Thymeleaf』『Velocity』,用法其實跟『JSP』差不太多,隻是它們的性能會更好。要麼前後端分離,後端隻需要傳回JSON給前端,頁面完全不需要後端管。

說了這麼多,我想說的是:“JSP還是有必要了解一下,不需要花很多時間,知道即可,這篇文章我就能帶你認識JSP”

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜
循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

什麼是JSP?

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

重複一句: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處理好的資料,做顯示使用:

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

JSP需要學什麼

JSP我們要學的其實兩塊就夠了:JSTL和EL表達式

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>
           

效果:

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

上面看起來,也沒有多複雜呀,那我們試試EL表達式的!

在2.jsp中讀取Session設定的屬性

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>

${name}

</body>
</html>
           

隻用了簡簡單單的幾個字母就能輸出Session設定的屬性了!并且輸出在浏覽器上!

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

使用EL表達式可以友善地讀取對象中的屬性、送出的參數、JavaBean、甚至集合!

JSTL

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>
           

效果:

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

作者:Java3y

連結:https://zhuanlan.zhihu.com/p/117238806

來源:知乎

驚喜

最後還準備了一套上面資料對應的面試題(有答案哦)和面試時的高頻面試算法題(如果面試準備時間不夠,那麼集中把這些算法題做完即可,命中率高達85%+)

循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜
循序漸進!2020還有必要學JSP嗎?已拿意向書!驚喜

/c:forEach>

效果:

[外鍊圖檔轉存中...(img-eQeGaJBF-1623501770549)]




作者:Java3y
連結:https://zhuanlan.zhihu.com/p/117238806
來源:知乎
# 驚喜

最後還準備了一套上面資料對應的面試題(有答案哦)和面試時的高頻面試算法題(如果面試準備時間不夠,那麼集中把這些算法題做完即可,命中率高達85%+)

[外鍊圖檔轉存中...(img-0PLtREIj-1623501770550)]


[外鍊圖檔轉存中...(img-980gBqXd-1623501770550)]

**[資料擷取方式:戳這裡免費領取](https://docs.qq.com/doc/DSmxTbFJ1cmN1R2dB)**
           

繼續閱讀