1、什麼是jsp,為什麼要使用jsp。
再使用idea建立完一個web工程後,在webapp目錄下會生成一個index.jsp

直接編譯運作,網站将自動打開這樣一個網頁:
是以我們可以推測這個index.jsp就是決定這個項目的初始頁面的HTML編碼的,這裡的hello-world是部署Tomcat時設定的。
是以其實JSP就是用來編寫HTML編碼的一種解決方案,那為什麼需要額外的這樣一套解決方案呢?
這是我之前對Servlet簡單的使用:
PrintWriter writer = resp.getWriter();
writer.append("<!DOCTYPE html>\r\n")
.append("<html >\r\n")
.append(" <head>\r\n")
.append(" <title>hello user application</title>\r\n")
.append(" </head>\r\n")
.append(" <body>\r\n")
.append(" Hello, ").append(user).append("!<br/><br/>\r\n")
.append(" <form action=\"first\" method=\"POST\">")
.append(" Enter your name:<br/>\r\n")
.append(" <input type=\"text\" name=\"user\"/><br/>\r\n")
.append(" <input type=\"submit\" value=\"Submit\"/>\r\n")
.append(" </form>\r\n")
.append(" </body>\r\n")
.append("</html>\r\n");
這是在像response添加正文,用于HTML的編碼,可以發現這裡HTML和Java結合得并不好,導緻代碼很長還很亂,特别是引号需要轉義符。是以其實我們應該把這一塊HTML編碼獨立出去,是以就有了這樣一套名為JSP(JavaServerPages)的混合解決方案,它結合了Java代碼和HTML标簽,JSP包括了所有的HTML标簽,以及内建的JSP标簽、自定義的JSP标簽以及表達式語言。
2、JSP在運作時的處理
- 其實JSP隻是一個精心設計的Servlet,JSP隻是一種文法糖,在運作的時候JSP代碼将由JSP編譯器進行轉換,它将解析出JSP代碼的特性并把它們轉換成Java代碼,由JSO建立得到的Java類都将實作Servlet,最後和其他Servlet一樣對請求做出響應。
- JSP和其他Servlet一樣有自己的生命周期,不同的Web容器不一樣,比如在Tomcat中JSP将在第一次請求到達之前被即時的轉換并編譯,對于之後的請求可以之間使用編譯好的JSP。而許多其他的容器則提供了在部署應用程式時預編譯所有的JSP選項。
3、JSP指令
JSP指令用來設定整個JSP頁面相關的屬性,如網頁的編碼方式和腳本語言。
- <%@ page ... %>提供了對JSP如何進行轉換、渲染和傳輸到用戶端的控制
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
其中language将告訴容器JSP使用的是那種腳本語言,contentType和charset将設定JSP頁面的MIME類型和字元編碼,
page指令相關的屬性:
buffer | 指定out對象使用緩沖區的大小 |
autoFlush | 控制out對象的 緩存區 |
contentType | 指定目前JSP頁面的MIME類型和字元編碼 |
errorPage | 指定當JSP頁面發生異常時需要轉向的錯誤處理頁面 |
isErrorPage | 指定目前頁面是否可以作為另一個JSP頁面的錯誤處理頁面 |
extends | 指定servlet從哪一個類繼承 |
import | 導入要使用的Java類 |
info | 定義JSP頁面的描述資訊 |
isThreadSafe | 指定對JSP頁面的通路是否為線程安全 |
language | 定義JSP頁面所用的腳本語言,預設是Java |
session | 指定JSP頁面是否使用session |
isELIgnored | 指定是否執行EL表達式 |
isScriptingEnabled | 确定腳本元素能否被使用 |
- JSP可以通過include指令來包含其他檔案。被包含的檔案可以是JSP檔案、HTML檔案或文本檔案。包含的檔案就好像是該JSP檔案的一部分,會被同時編譯執行。
<%@ include file="檔案相對 url 位址" %>
- JSP API允許使用者自定義标簽,一個自定義标簽庫就是自定義标簽的集合。Taglib指令引入一個自定義标簽集合的定義,包括庫路徑、自定義标簽。
<%@ taglib uri="uri" prefix="prefixOfTag" %>
4、在JSP中使用Java
jsp中寫java代碼有如下三種方式:
<%! %>,這裡面可以申明變量或方法,注意:這裡面申明的變量是全局的
<% %>,與上面的方法相比,這個方法的局部的
<%= %>,用于輸出表達式到浏覽器,注意:這裡面的表達式不能跟分号
- 使用JSP中的隐式變量
JSP檔案提供了幾個可以在腳本和表達式中可以使用的隐式變量,這些變量不需要在任何位置定義即可使用它們,JSP規範要求JSP的轉換器和編譯器提供這些變量,名字也要完全相同。從一個編譯後的JSP檔案中可以看到這樣一些代碼片段
1 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
2 throws java.io.IOException, javax.servlet.ServletException {
3
4 final javax.servlet.jsp.PageContext pageContext;
5 javax.servlet.http.HttpSession session;
6 final javax.servlet.ServletContext application;
7 final javax.servlet.ServletConfig config;
8 javax.servlet.jsp.JspWriter out = null;
9 final java.lang.Object page = this;
10 javax.servlet.jsp.JspWriter _jspx_out = null;
11 javax.servlet.jsp.PageContext _jspx_page_context = null;
12
13 try {
14 response.setContentType("text/html; charset=UTF-8");
15 pageContext = _jspxFactory.getPageContext(this, request, response,
16 null, false, 8192, true);
17 _jspx_page_context = pageContext;
18 application = pageContext.getServletContext();
19 config = pageContext.getServletConfig();
20 out = pageContext.getOut();
21 _jspx_out = out;
22 }
這裡總共定義了8個隐式變量,分别是:
- request、response
HttpServletRequest類和HttpServletResponse類的執行個體
- pageContext
PageContext類的執行個體,提供對JSP頁面所有對象以及命名空間的通路
- session
HttpSession類的執行個體,如果在page指令中的session特性設定為假那麼JSP中就沒有這個變量
- application、
ServletContext類的執行個體,與應用上下文有關
- config、
ServletConfig類的執行個體,可以使用該對象通路JSP Servlet的配置,例如Servlet初始化參數
- out、
JspWriter類的執行個體,用于把結果輸出至網頁上
- page
類似于Java類中的this關鍵字,提供了請求特性和回話特性值、通路請求和響應、包含其他檔案、轉發請求的幾個便利方法
最後還有一個exception這裡沒有出現,這個變量需要通過page指令的isErrorPage特性設定為真,表示該JSP的目的是用于處理錯誤,才會出現這個變量。
建立一個first.jsp檔案,添加以下的代碼
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%!
private static final String DEFAULT_USER = "Guest";
%>
<%
String user = request.getParameter("user");
if(user == null){
user = DEFAULT_USER;
}
%>
<!DOCTYPE html>
<html>
<head>
<title>first user application</title>
</head>
<body>
hello, <%= user %> ! <br/><br/>
<form action="first.jsp" method="post">
輸入使用者名:<br/>
<input type="text" name="user"/><br/>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
編譯運作,在浏覽器中輸入http://localhost:8080/hello-world/first.jsp就可以得到下面這個網頁
這裡就實作了之前的Servlet,不過其實并不應該在JSP中使用Java
5、注釋
在JSP中實作代碼注釋的方法有四種:
- XML注釋
<!-- 這是被注釋的内容 -->
但是這種類型的注釋将被發送到用戶端,浏覽器将會忽略它,但是它會出現在響應的源代碼中注釋中的任何JSP代碼都将會被處理,
<!-- 這是被注釋的内容<%!private static final String DEFAULT_USER = "Guest";%> -->
這裡的java代碼就将會被執行。
- 傳統的java行注釋以及java塊注釋,也就是//...和
<%
String user = request.getParameter("user");
// if(user == null){
// user = DEFAULT_USER;
// }
/*
String pwd = req.getParameter("pwd");
String sex = req.getParameter("sex");
*/
%>
- JSP注釋
<%-- JSP注釋掉的内容 --%>
6、結合使用Servlet和JSP
- 配置部署描述符中的JSP屬性
在空的web.xml檔案(隻包含<display-name>)中,添加以下内容:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspf</url-pattern>
<page-encoding>UTF-8</page-encoding>
<scripting-invalid>false</scripting-invalid>
<include-prelude>/WEB-INF/jsp/base.jspf</include-prelude>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
<default-content-type>text/html</default-content-type>
</jsp-property-group>
</jsp-config>
标簽<jsp-config>中可以包含任意數目的</jsp-property-group>标簽,這個屬性用于區分不同JSP組的屬性。例如為/WEB-ING/JSP/admin檔案夾中所有的JSP定義一組通用的屬性,為/WEB-ING/JSP/help定義另一組屬性,那麼需要通過定義<url-pattern>标簽來區分不同的屬性組,其中一個被設定為<url-pattern>/WEB-ING/JSP/admin/*.jsp</url-pattern>,另一個則被設定為<url-pattern>/WEB-ING/JSP/help/*.jsp</url-pattern>。
<include-prelude>标簽将告訴容器在所有屬于該屬性組中的JSP的頭部添加檔案/WEB-INF/jsp/base.jspf,可以用于定義公共變量、标簽庫聲明或共享其他可作用于屬性組所有的JSP資源。類似的<include-coda>标簽定義了包含在組中所有JSP尾部的檔案。在一個JSP組中可以同時多次使用這些标簽。
<page-encoding>與page指令的pageEncoding特性一緻,因為JSP的預設内容類型為text/html,是以隻需要通過<page-encoding>将字元編碼設定為UTF-8即可。還可以使用<default-content-type>标簽以其他預設的内容類型覆寫text/html。
<trim-directive-whitespaces>标簽告訴JSP轉換器删除響應輸出中的空白,隻保留由指令、聲明、腳本和其他JSP标簽建立的文本。
<scripting-invalid>标簽設定為假時:允許在組中的所有JSP中使用Java。如果把這個設定為真,在組中使用Java将引起轉換錯誤。标簽<el-ignored>的作用類似,不過它對應的是page指令中的isELIgnored特性。如果它的值為真,那麼組内的JSP将禁止使用表達式語言。它的預設值同樣為假。
<%@ page import="model.Ticket, model.Ticket" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
以上是base.jspf的内容,該代碼完成了兩件事情:為所有的JSP導入這些類,并聲明JSPL核心代碼庫。
這是webapp的檔案結構,将檔案添加到WEB-INF下可以阻止使用者通過浏覽器通路這些JSP,因為WEB-INF目錄中的檔案是禁止通過Web通路的。依賴于由重定向Servlet和JSP提供的回話和請求特性的JSP都可以添加到WEB-INF中。
先寫一個簡單的jsp:
<%@ page session="false" %>
<!DOCTYPE html>
<html>
<head>
<title>Customer Support</title>
</head>
<body>
<h2>Create a Ticket</h2>
<form method="POST" action="tickets" enctype="multipart/form-data">
<input type="hidden" name="action" value="create"/>
Your Name<br/>
<input type="text" name="customerName"><br/><br/>
Subject<br/>
<input type="text" name="subject"><br/><br/>
Body<br/>
<textarea name="body" rows="5" cols="30"></textarea><br/><br/>
<b>Attachments</b><br/>
<input type="file" name="file1"/><br/><br/>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
然後建立一個簡單的Servlet在加上代碼:
@WebServlet(
name = "TestServlet",
urlPatterns = {"/test"}
)
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/jsp/view/ticketForm.jsp")
.forward(request, response);
}
}
然後在使用浏覽器通路http://localhost:8080/hello-world/test時就是在通路這個JSP了
轉載于:https://www.cnblogs.com/xxbbtt/p/8375828.html