淺談 JSP 技術

JSP全稱jave server pages。jsp是服務端的技術,需要服務器編譯翻譯成servlet才能使用。jsp出現之前一直是HTML在做web的顯示工作,用戶通過http請求訪問網站,servlet將內部html資源跳轉過去供用戶瀏覽。但是那些靜態資源的展示不足以滿足用戶的需求,網站的定位更多的在於提高訪問量,獲取更多的用戶信息。一開始通過使用servlet的response.write()在服務端將一些動態的信息發送到顯示界面,我們的serlvet程序看起來會非常的臃腫,難以維護和擴展。於是jsp的出現很好的彌補了servlet的短板,它用來展示一些動態的數據使得開發人員的開發效率大大提高。並且簡單易學,不熟悉servlet開發的也可以使用jsp技術完成網站開發。

不能說是jsp替代了servlet,只能說它是servlet的強力助手,因爲這樣一來,我們的網站結構中servlet只業務邏輯和轉發,jsp只用來做界面展示。

在jsp中我們可以寫java代碼,也可以寫html標籤,又能使用css、jquery技術,所以說jsp是各種技術的結合,並且技術之間的耦合性幾乎沒有。

爲什麼說jsp就是sevlet

在服務器端編寫好jsp代碼時,發佈應用後,我們的web目錄中會出現work的目錄,是用來存放編譯後的jsp的.java代碼和class文件。如圖
這裏寫圖片描述
那再來看看java文件中的內容

開頭部分的註釋是由服務器jsp引擎編寫的,指出jsp的被創建者,創建時間,最後修改時間

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/7.0.64
 * Generated at: 2016-12-09 13:43:59 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */

導包部分,默認的三個包和一個代碼中使用到的util的包


package org.apache.jsp.view;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;

主類程序塊


public final class transfer_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> 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() {
  }

主要服務邏輯代碼,將需要展示的數據通過out對象write出各種html標籤,展示一個靜態的頁面

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.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("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
      out.write("<html>\r\n");
      out.write("  <head>\r\n");
      out.write("  \r\n");
      out.write("\r\n");
      out.write("  </head>\r\n");
      out.write("  \r\n");
      out.write("  <body>\r\n");
      out.write("   \t<form action=\"");
      out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${pageContext.request.contextPath }", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null, false));
      out.write("/transferservlet\"method=\"post\">\r\n");
      out.write("   \t\t<table>\r\n");
      out.write("   \t\t\t<tr>\r\n");
      out.write("   \t\t\t\t<td>轉入賬戶</td>\r\n");
      out.write("   \t\t\t\t<td><input type=\"text\" name=\"incount\"/></td>\r\n");
      out.write("   \t\t\t</tr>\r\n");
      out.write("   \t\t\t<tr>\r\n");
      out.write("   \t\t\t\t<td>轉出賬戶</td>\r\n");
      out.write("   \t\t\t\t<td><input type=\"text\" name=\"outcount\"/></td>\r\n");
      out.write("   \t\t\t</tr>\r\n");
      out.write("   \t\t\t<tr>\r\n");
      out.write("   \t\t\t\t<td>交易金額</td>\r\n");
      out.write("   \t\t\t\t<td><input type=\"text\" name=\"money\"/></td>\r\n");
      out.write("   \t\t\t</tr>\r\n");
      out.write("   \t\t\t<tr>\r\n");
      out.write("   \t\t\t\t<td colspan=\"2\" align=\"left\"><input type=\"submit\" value=\"確認交易\"/></td>\r\n");
      out.write("   \t\t\t\t\r\n");
      out.write("   \t\t\t</tr>\r\n");
      out.write("   \t\t</table>\r\n");
      out.write("   \t</form>\r\n");
      out.write("  </body>\r\n");
      out.write("</html>\r\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

JSP最佳實踐,即MVC模式

在長期的實戰中,人們得出如下習慣用法:
顯示View:JSP適合做頁面的顯示,例如:顯示登錄成功界面
控制Controller:Servlet適合做業務控制操作,例如:接收用戶請求,將用戶請求的參數值封裝到JavaBean對象中去,調用其它Java類處理,如果有結果,將結果放入到域對象中去,轉發或重定向到顯示結果的JSP頁面
功能Model:Bean,即就是普通Java類,該類中封裝大量的業務操作

JSP語法

  1. JSP輸出表達式
    <%= ”xx” %>,主要用於向瀏覽器輸出變量的值
    注意:<%=和%>不可分隔,後面無分號

  2. JSP腳本片斷
    <% Java代碼; %>
    書寫一行或多行Java代碼,多個腳本片段可以相互訪問,
    注意:後面有分號,多個腳本片段之間可以相互調用

  3. JSP聲明
    <%! java代碼 %>
    JSP聲明的變量或方法,會被翻譯成Servlet的實例變量和成員方法

  4. JSP註釋

    1. JSP中可以書寫Java代碼,所有Java代碼的註釋在JSP同樣可以使用//
    2. JSP中可以書寫HTML代碼,所有HTML代碼的註釋在JSP同樣可以使用
    3. JSP也有自已特有的註釋,<%– xxxxxx –>,不能嵌套
    4. JSP引擎將當作有效內容,翻譯進Servlet源文件
    5. JSP引擎將<%– –%>當作無效內容,忽略,不翻譯進Servlet源文件,推薦使用

JSP指令 ##

JSP指令是通知JSP引擎如何處理該JSP頁面,總共三種指令:page指令、include指令、taglib指令
先扒一段頭文件指令,再一一介紹。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
  1. page指令
<@page [ language="java" ] 默認java, 在JSP的腳本片段只能書寫java代碼 [import="{package.class|package.*},..] 默認java.lang,javax.servlet,javax.servlet.http,javax.servlet.jsp向jsp翻譯後的servlet源碼導入包
[ session="true | false" ] 默認true,true表示一旦訪問jsp頁面,自動創建HttpSession,false表示不自動創建HttpSession.
[ autoFlush="true | false" ] 默認true,jsp頁面有緩存,在默認情況下,autoFlush=true表示緩存滿後自動強行輸出到瀏覽器,如果設置爲false的話,得通過人工調用flush()方法纔可以輸出到瀏覽器
[ isThreadSafe="true | false" ] 默認true
jsp頁面是否被多個線程同時訪問安全?
如果設置爲true,表示多個線程來訪問jsp是安全的,如果設置爲false的話,就表示該jsp頁面在沒有加鎖的情況下,多個線程來訪問,可能會出現安全問題
[ info="hello" ] 默認""表示給該jsp頁面記錄一些附加的信息
[ errorPage="relative_url" ] 無默認值,表示該jsp頁面出錯後,轉發到指定的jsp頁面進行錯誤消息的顯示
/表示當前web應用的根目錄,否則表示當前jsp頁面          [ isErrorPage="true | false" ] 默認false
如果是用於錯誤消息的顯示jsp頁面,要加isErrorPage=true這個屬性,這樣jsp引擎就會創建exception內置對象,該exception內置對象中封裝了出錯的原因.如果設置爲false的話,jsp引擎不會將exception內置對象翻譯到servlet代碼中,即無法在jsp頁面中用exception對象來獲取出錯原因
  1. include指令
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ include file="/jsp/date.jsp"%>
<%@ include file="/jsp/el.jsp"%>

在一個JSP頁面中包含多個其它的JSP頁面 <%@ include file=”被包含的jsp頁面的路徑”%> 在翻譯成Servlet時,就將被包含的JSP頁面中的內容翻譯成Servlet中了,即多個JSP只會翻譯成1個Servlet

  1. taglib指令
    在JSP頁面中需要引用第三方的標籤<%@ taglib uri=”名稱空間” prefix=”標籤的前綴”%>

JSP九大內置對象

由JSP引擎將JSP翻譯成Servlet時,自動創建的對象,無需程序員創建的對象,直接使用即可,這些對象就叫內置對象。

  1. request : HttpServletRequest請求對象,請求域對象
  2. response: HttpServletResponse 響應對象
  3. session : HttpSession 會話域對象
  4. application : ServletcContext 應用域對象
  5. config : ServletConfig獲取某個Servlet的初始化參數
  6. out : JspWriter(帶緩衝的PrintWriter) JSP專用的字符輸出對象
  7. exception: exception (特殊情況下用) 異常對象
  8. page: page this(本JSP頁面) JSP頁面自己
  9. pageContext: 當前域對象
    pageContext功能強大,其中有一個findAttribute()這個API,它會依次從page->request->session->application這幾個域對象,例如:
    如果在request中找到了,就不會再去其它域對象中找了
    如果在JSP中的上述四個域對象都沒找到,返回null
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章