單純用Servlet其實可也寫網頁, 只要把網頁內容全部調用response.getWritter方法把整個網頁寫進去就可以了, 但是這樣很笨比, 顯然不能這麼寫;
就像PHP一樣, jsp是把java語言直接內嵌寫在html裏面;
開頭這樣寫
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%>
在導入其他類的時候
,如果導入多個類,彼此用,逗號隔開,像這樣 import="java.util.*,java.sql.*"
jsp的本質其實是Servlet, 編譯之後jsp會被編譯成Servlet;
jsp由這些頁面元素組成:
- 靜態內容
就是html,css,javascript等內容 - 指令
以<%@開始 %> 結尾,比如<%@page import=“java.util.*”%> - 表達式 <%=%>
用於輸出一段html - Scriptlet
在<%%> 之間,可以寫任何java 代碼 - 聲明
在<%!%> 之間可以聲明字段或者方法。但是不建議這麼做。 - 動作
<jsp:include page=“Filename” > 在jsp頁面中包含另一個頁面。在包含的章節有詳細的講解 - 註釋 <%-- – %>
不同於 html的註釋 通過jsp的註釋,瀏覽器也看不到相應的代碼,相當於在servlet中註釋掉了
<%=%>和 <%out.println()%>是等價的, 就是輸出一個字符串;
所以比如說要用for循環來輸出一個表格應該這樣做:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%
List<String> words = new ArrayList<String>();
words.add("today");
words.add("is");
words.add("a");
words.add("great");
words.add("day");
%>
<table width="200px" align="center" border="1" cellspacing="0">
<%for (String word : words) {%>
<tr>
<td><%=word%></td>
</tr>
<%}%>
</table>
jsp中有include這個東西, 可以是一個指令也可以是一個動作,
如果是指令include
<%@include file="footer.jsp" %>
footer.jsp的內容會被插入到 hello.jsp 轉譯 成的hello_jsp.java中,最後只會生成一個hello_jsp.java文件
如果是動作include
<jsp:include page="footer.jsp" />
footer.jsp的內容不會被插入到 hello.jsp 轉譯 成的hello_jsp.java中,還會有一個footer_jsp.java獨立存在。 hello_jsp.java 會在服務端訪問footer_jsp.java,然後把返回的結果,嵌入到響應中。
因爲指令<%@include 會導致兩個jsp合併成爲同一個java文件,所以就不存在傳參的問題,在發出hello.jsp 裏定義的變量,直接可以在footer.jsp中訪問。
而動作<jsp:include />其實是對footer.jsp進行了一次獨立的訪問,那麼就有傳參的需要。
如本例:
- 在hello.jsp中使用動作<jsp:include,並通過<jsp:param 帶上參數
<jsp:include page="footer.jsp">
<jsp:param name="year" value="2017" />
</jsp:include>
- 在footer.jsp中,使用request.getParameter(“year”)取出year
所以我覺得還是用指令比較好;
JSP做客戶端和服務器端跳轉也和Servlet裏一樣可以:
response.sendRedirect("hello.jsp");//客戶端跳轉
request.getRequestDispatcher("hello.jsp").forward(request, response);//服務器端跳轉
<jsp:forward page="hello.jsp"/>//使用jsp的指令簡化的來做服務器端跳轉
在JSP中可以使用Cookie
設置Cookie:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
Cookie c = new Cookie("name", "Gareen");
c.setMaxAge(60 * 24 * 60);
c.setPath("/");
response.addCookie(c);
%>
<a href="getCookie.jsp">跳轉到獲取cookie的頁面</a>
然後是獲取Cookie的方法:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
Cookie[] cookies = request.getCookies();
if (null != cookies)
for (int d = 0; d <= cookies.length - 1; d++) {
out.print(cookies[d].getName() + ":" + cookies[d].getValue() + "<br>");
}
%>
同樣的在JSP中也可以用Session, 設置Session:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
session.setAttribute("name", "teemo");
%>
<a href="getSession.jsp">跳轉到獲取session的頁面</a>
獲取Session內容的方法:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
String name = (String)session.getAttribute("name");
%>
session中的name: <%=name%>
Session和Cookie的區別有一個很重要的點在於, 其實Session是保存在服務器端的, 而Cookie是保存在客戶端本身的;
如果不是第一次訪問瀏覽器的話, 客戶端本身是有Cookie的, 那麼會同時傳過去一個jsessionid, 這就會在服務器端對應一個Session, 這時候服務器端就不會創建一個新的Session, 而是根據這個id找到之前已經創建過的Session;
如果瀏覽器把cookie功能關閉,那麼服務端就無法獲取jsessionid,每一次訪問,都會生成一個新的session對象。
沒有Cookie的時候, 如果還是想要找到之前的session, 可以這樣做:
response.encodeURL("getSession.jsp")
response.encodeURL方法會把getSession.jsp這個url轉換爲
getSession.jsp;jsessionid=22424AEA86ADBE89F335EEB649D997A8
通過這個方式,提交jsessionid到服務器。 服務器根據這個jsessionid匹配到對應的session. 與session相關的功能,就可以正常工作了。
在jsp裏面這樣:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="javax.servlet.http.Cookie"%>
<%
session.setAttribute("name", "teemo");
%>
<a href="<%=response.encodeURL("getSession.jsp")%>">跳轉到獲取session的頁面</a>
然後在默認的tomcat配置中, session會保存30分鐘;
JSP有4個作用域
1.pageContext 當前頁面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
pageContext.setAttribute("name","gareen");
%>
<%=pageContext.getAttribute("name")%>
2.requestContext 一次請求
requestContext指的是一次請求
如果發生了服務端跳轉,從setContext.jsp跳轉到getContext.jsp,這其實,還是一次請求。 所以在getContext.jsp中,可以取到在requestContext中設置的值
客戶端跳轉,瀏覽器會發生一次新的訪問,新的訪問會產生一個新的request對象。
所以頁面間客戶端跳轉的情況下,是無法通過request傳遞數據的。
常用寫法是
request.setAttribute("name","gareen");
request.getAttribute("name")
但是也可以用pageContext來做,寫成
pageContext.setAttribute("name","gareen",pageContext.REQUEST_SCOPE);
pageContext.getAttribute("name",pageContext.REQUEST_SCOPE)
3.sessionContext 當前會話
jsp裏面這樣寫
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
session.setAttribute("name","gareen");
response.sendRedirect("getContext.jsp");
%>
也可以這樣:
pageContext.setAttribute("name","gareen",pageContext.SESSION_SCOPE);
pageContext.getAttribute("name",pageContext.SESSION_SCOPE)
4.applicationContext 全局,所有用戶共享
可以這樣寫:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
application.setAttribute("name","gareen");
System.out.println(application == request.getServletContext());
response.sendRedirect("getContext.jsp");
%>
也可以這樣
pageContext.setAttribute("name","gareen",pageContext.APPLICATION_SCOPE);
pageContext.getAttribute("name",pageContext.APPLICATION_SCOPE)
JSP的隱式對象指的是不需要顯示定義,直接就可以使用的對象
JSP一共有9個隱式對象,分別是
request,response,out
pageContext, session,application
page,config,exception
request,response,out
request, response, out 就對應 請求, 響應, 和直接輸出到網頁上;
page,config,exception
page 對象即表示當前對象
JSP 會被編譯爲一個Servlet類 ,運行的時候是一個Servlet實例。 page即代表this
config可以獲取一些在web.xml中初始化的參數。
在JSP中使用config比較複雜,需要如下幾個步驟
- 在web.xml中進行配置
- 創建一個testconfig.jsp
通過config.getInitParameter(“database-ip”) 獲取參數 - 訪問路徑,獲取web.xml中配置的參數
exception 對象只有當前頁面的<%@page 指令設置爲isErrorPage="true"的時候纔可以使用。
同時,在其他頁面也需要設置 <%@page 指令 errorPage="" 來指定一個專門處理異常的頁面。
-
準備一個try.jsp
設置errorPage=“catch.jsp”,表示有異常產生的話,就交給catch.jsp處理
故意在裏面造成數組越界異常 -
準備一個catch.jsp
設置 isErrorPage=“true”,表示當前頁面可以使用exception對象