一、什麼是jsp,爲何要使用jsp。html
再使用idea建立完一個web工程後,在webapp目錄下會生成一個index.jspjava
直接編譯運行,網站將自動打開這樣一個網頁:web
因此咱們能夠推測這個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標籤以及表達式語言。session
二、JSP在運行時的處理app
三、JSP指令webapp
JSP指令用來設置整個JSP頁面相關的屬性,如網頁的編碼方式和腳本語言。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 | 肯定腳本元素可否被使用 |
<%@ include file="文件相對 url 地址" %>
JSP API容許用戶自定義標籤,一個自定義標籤庫就是自定義標籤的集合。Taglib指令引入一個自定義標籤集合的定義,包括庫路徑、自定義標籤。
<%@ taglib uri="uri" prefix="prefixOfTag" %>
四、在JSP中使用Java
jsp中寫java代碼有以下三種方式:
<%! %>,這裏面能夠申明變量或方法,注意:這裏面申明的變量是全局的
<% %>,與上面的方法相比,這個方法的局部的
<%= %>,用於輸出表達式到瀏覽器,注意:這裏面的表達式不能跟分號
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個隱式變量,分別是:
HttpServletRequest類和HttpServletResponse類的實例
PageContext類的實例,提供對JSP頁面全部對象以及命名空間的訪問
HttpSession類的實例,若是在page指令中的session特性設置爲假那麼JSP中就沒有這個變量
ServletContext類的實例,與應用上下文有關
ServletConfig類的實例,可使用該對象訪問JSP Servlet的配置,例如Servlet初始化參數
JspWriter類的實例,用於把結果輸出至網頁上
相似於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
五、註釋
在JSP中實現代碼註釋的方法有四種:
<!-- 這是被註釋的內容 -->
可是這種類型的註釋將被髮送到客戶端,瀏覽器將會忽略它,可是它會出如今響應的源代碼中註釋中的任何JSP代碼都將會被處理,
<!-- 這是被註釋的內容<%!private static final String DEFAULT_USER = "Guest";%> -->
這裏的java代碼就將會被執行。
<% String user = request.getParameter("user"); // if(user == null){ // user = DEFAULT_USER; // } /* String pwd = req.getParameter("pwd"); String sex = req.getParameter("sex"); */ %>
<%-- JSP註釋掉的內容 --%>
六、結合使用Servlet和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了