Servlet、JSP入門知識和新手學習過程中的總結『不斷更新』
目錄
一.Servlet
what is servle? 何謂Servlet Container?
Servlet是瀏覽器引起程式在伺服器上執行的一種技術,由伺服器執行必要的計算,也許還需要訪問資料庫,最終把HTML輸出返回給客戶端上的瀏覽器。
Servlet Container就是能夠執行Servlet的伺服器,一般來說能夠執行Servlet的伺服器就能夠執行JSP。
因為JSP --> servlet(.java) --> .class
『運作模式』servlet process flow
Servlet 是 server 端處理 client request 的 class,負責處理 request 的資料,可與 database 資料及其它 class 溝通,若干邏輯運算完畢後,再把結果 response 至 client。
『servlet生命週期』the servlet life cycle
『原生servlet』PrimitiveServlet
package com.icsc.servlet; import javax.servlet.*; import java.io.IOException; import java.io.PrintWriter; public class PrimitiveServlet implements Servlet { public void init(ServletConfig config) throws ServletException { System.out.println("init"); } public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("from service"); PrintWriter out = response.getWriter(); out.println("Hello.Roses are red."); out.print("Violets are blue."); } public void destroy() { System.out.println("destroy"); } public String getServletInfo() { System.out.println("getServletInfo"); return null; } public ServletConfig getServletConfig() { System.out.println("getServletConfig"); return null; } }
『Servlet程式架構』Servlet program architecture
package com.icsc.servlet.web; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class helloWorldServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); out.println("<H3>Hello World!</H3>"); } }
二.JSP
What’s Java Server Page
JSP Syntax『JSP語法』
<% 存放標準 Java 程式程式碼 %>
<%!變數、方法和類別宣告區(Declarations)%>
<%=輸出表示式%>
<%=foo%>在頁面上顯示變數foo的值
<%-- 批註區--%>
<%@ 編譯指令 屬性=“屬性值”%>
編譯指令:page、include
(1).變數和方法的申明
<%! public static final String _AppId = "IS06"; %>
<%! // 轉化數字格式
String formatNum(BigDecimal bg){
try {
if(bg.compareTo(new BigDecimal(0)) > 0 )
return new DecimalFormat("###,###,##0").format(bg);
else
return "" ;
}catch(Exception e){
return "*";
}
}
%>
(2).常用 Jsp 編譯指令
<%@ page import=“java.io.*,java.sql.*” %>
import 其它的 package, 可以用 , 分開不同的 package , 或寫 2 個 <%@ page import=“…” %>.
<%@ page contentType=“text/html; charset=GB2312” %>
設定目前本頁的檔案內容格式,及用何種編碼.
<%@ include file=“/erp/jsp/dzjjmenu.jsp” %>
引用其它的 jsp file ,在轉成 servlet code 的時候,會把這 file 的內容也 include 進來,最後只會轉成一個 servlet class.
Implicit Objects
隱含物件就是在Jsp中不需要事先做任何宣告就可以使的一些物件。每個隱含物件所用到類別、介面都被定義在Java Servlet API package中。
與servlet有關的隱含物件:page、config
與Input/output有關的隱含物件:out、request、response
Jsp執行時,提供有關Context的隱含物件:session、application、pageContext
與Error有關的隱含物件:exception
(1).Request Object
每支 Jsp 會自動產生 request 的object ,此 object 主要用作傳遞 client 的一些 information.
例如 : Server 處理 client 的資料(如會員登入)都是透過此 object 來取得資料。
<input type=“text” name=“myName” value=“InfoChamp”>, submit 送至 server 處理時,
處理的 Jsp 需要用 String aa = request.getParameter(“myName”) ;
getParameterNames()
回傳窗體送出的欄位名稱,取得這些名稱後自然也能取得對應的 value, 有時對 debug 蠻有幫助。
getParameterValues(String name)
取得相同名稱的欄位資料,所有結果會儲存在一個 String[] 中。
getSession()
取得使用者的 session Object。
setAttribute(String key, Object o)
可以把一些 object 暫時儲存在 request 中。
getAttribute(String key)
取得以此 key 存在 request 中的 object
(2).Response Object
用來設定伺服器端迴應給客戶端網頁的狀態。
//取得檔案內容的編碼方式
response.getCharacterEncoding();
//設定網頁的檔案格式與編碼方式
方式1:<%@page contentType = “text/html; charset=UTF-8”%>
方式2:response.setContentType(“text/html; charset=UTF-8”);
//輸出錯誤訊息到客戶端
response.sendError(錯誤程式碼,文字訊息);
//將網頁重新導向新網頁
response.sendRedirect(“網頁地址”);
(3).application Object
Application對伺服器而言,可以視為一個所有上線者可共用的存取區,application的資料是程式設定其值時被初始化,當關閉網頁伺服器或者超過預設時間而未有任何使用者連時自動消失。
建立application引數
application.setAttribute(“引數名稱”, “引數內容”)
傳回application引數
application.getAttribute(“引數名稱”)
移除application引數
application.removeAttribute(“引數名稱”)
傳回所有application引數
application.getAttributeNames(“引數名稱”)
(4).Out Object
每支 Jsp 會自動產生 out 的object - javax.servlet.jsp.JspWriter , 此object 主要用於把資料印在網頁上 。
println(String content)
把資料印在網頁上,雖然這來是 println ,實際要在網頁中換行時還是要印一個 <br>
close()
終止網頁的印出,通常用在 debug 的時候。
flush()
把目前存在暫存區中的資料全部印出,此 method 只有在 isAutoFlush() 為 false 時才有意義。
(5).Session Object
(1).What Session
Session 是伺服器端上線使用者的存取區,存放的是使用者的個別資料。
Session –交談時期,在一段時間內 client 與 server 的互動作用。這段時間內,server 會儲存 client的一些資訊,並以一個 session id 作為辨認,在 client 寫下一個 session id. 每當 server 收到 client 的 request 後,server 會以這 session id 在 server 上來尋找所有關於此 client 的資訊。由於 client 的所有資訊都是暫存在 server 的 memory中,會耗 server 的 resource. 所以 session 儘量不要使用太多。
當 client 連上 server 一段時間都沒有再送出 request , server 就會把該筆 session 的資訊清除。
每一個 Jsp file 都會自動產生一個叫 session 的object. 本身是屬於 javax.servlet.http.HttpSession 的 class。
三.學習中遇到的一些基本問題
1.解決doPost呼叫doGet方法中文亂碼問題
在doGet方法中新增【且一定要寫在獲取引數之前】
//解決編碼問題
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
2.Spring Tool Suit 如何改變頁面的編碼方式(一般預設的時iso-8859-1改為utf-8)
這個工具預設的編碼是ISO-8859-1的西歐文字編碼。為了設定成utf-8,還是折騰了一下。
總共設定了以下幾個地方:
1、windows--preferences--general--workspace,Text file encoding設定成utf-8
2、windows--preferences--general--content types,把裡面text的default encoding整個無腦update成utf-8
3、windows--preferences--web--jsp files,把這裡的encoding設定成utf-8
3.PrintWriter out = response.getWriter(); 是什麼意思?
//打個通俗的比方就是通過HttpServletResponse物件得到一支筆,
//然後就可以用out.print()方法在網頁上寫任何你想顯示的內容。
[1] 伺服器端跳轉:
(1).forward跳轉:<jsp:forward page ="跳轉頁面地址"> //伺服器端的跳轉
- 伺服器端跳轉,位址列不改變。url上的地址不變,說明是伺服器端的跳轉;
- 執行到跳轉語句後馬上執行跳轉,之後的程式碼不再執行(跳轉之前一定要釋放全部資源)。
- request設定的屬性在跳轉後的頁面仍然可以使用。
(2).request.getRequestDispatcher("ngLoad.jsp")
//舉例:用於使用者名稱密碼錯誤提示
//在XX.java(servlet)上寫:
request.setAttribute("message", "失敗");
request.getRequestDispatcher("ngLoad.jsp").forward(request, response);
//在XX.jsp上寫:
<%
String message=(String)request.getAttribute("message");
if (message == "失敗") {
%>
<p style="color:red; margin:0;padding:0;">使用者名稱或密碼錯誤</P>
<%
}
%>
[2] 客戶端端跳轉:
response.sendRedirect("HelloWorld.jsp"); //客戶端的跳轉
return;
一定注意:跳轉之後該語句之後的程式碼會繼續執行!!所以請加上return;
- 客戶端跳轉,位址列改變。url上的地址變化,說明是客戶端的跳轉;
- 所有程式碼執行完畢後跳轉。
- 跳轉後頁面不能使用上一個頁面的request。
- 使用地址重寫傳遞引數(response.sendRedirect("URL?引數名=引數值"))。
response.setHeader("refresh","1;URL=http://localhost:8080/Demozxj/Demozxj/load.html");//停留1秒
5.獲取路徑的幾種方法
${pageContext.request.contextPath}是JSP取得絕對路徑的方法,等價於<%=request.getContextPath()%> ,也就是取出部署的應用程式名或者是當前的專案名稱。
比如我的專案名稱是demo1在瀏覽器中輸入為http://localhost:8080/demo1/a.jsp
${pageContext.request.contextPath}或<%=request.getContextPath()%>取出來的就是/demo1,而"/"代表的含義就是http://localhost:8080
故有時候專案中這樣寫${pageContext.request.contextPath}/a.jsp
//獲取上下文路徑
out.println("<h1>" + request.getContextPath() + "</h1>");
//獲取絕對路徑
out.println("<h5>" + request.getSession().getServletContext().getRealPath("/") + "</h5>");
舉例:http://localhost:8080/app/testJsp.jsp
<%=request.getContextPath()%> 獲取專案的根路徑 // /app
<%=request.getServletPath()%> 得到相對專案的url,不帶專案名稱 //testJsp.jsp
<%=request.getRequestURI()%> 獲取根路徑到地址結尾 // /app/testJsp.jsp
<%=request.getRealPath("/")%> 工程檔案的實際物理路徑 //D:\sts_workspace\
<%=request.getScheme() %> 返回當前頁面使用的協議 //http 或是 https
<%=request.getServerName()%> 返回當前頁面所在的伺服器主機的名字
<%=request.getServerPort()%> 返回伺服器接受此請求所用的埠號
其它:
1. getServletPath():獲取能夠與“url-pattern”中匹配的路徑,注意是完全匹配的部分,*的部分不包括。
2. getPageInfo():與getServletPath()獲取的路徑互補,能夠得到的是“url-pattern”中*d的路徑部分
3. getContextPath():獲取專案的根路徑
4. getRequestURI:獲取根路徑到地址結尾
5. getRequestURL:獲取請求的地址連結(瀏覽器中輸入的地址)
6. getServletContext().getRealPath(“/”):獲取“/”在機器中的實際地址
7. getScheme():獲取的是使用的協議(http 或https)
8. getProtocol():獲取的是協議的名稱(HTTP/1.11)
9. getServerName():獲取的是域名(xxx.com)
10. getLocalName:獲取到的是IP
6.getAttribute和getParameter的區別
(1)、getParameter()方法
getParameter的中文意思就是獲取引數,那麼這個方法的作用就是用來獲取引數的,它得到的是String型別。或者是用於讀取提交的表單中的值,或是是某個表單提交過去的資料。getParameter()是獲取POST/GET傳遞的引數值;它用於客戶端重定向時,即點選了連結或提交按扭時傳值用,即用於在用表單或url重定向傳值時接收資料用。getParameter只是應用伺服器在分析你送上來的request頁面的文字時,取得你設在表單或url重定向時的值。 當兩個web元件之間為連結關係時,被連結的元件同個getParameter方法來獲得請求引數。例子如下:
String itemNoOrName=request.getParameter("itemNoOrName")==null ? "":request.getParameter("itemNoOrName");
(2)、getAttribute()方法
它是一個函式。它只有一個引數。那個引數就是我們使用getElementById()或者使用getElementByTagName()方法取出來的節點元素的屬性名稱。取得屬性的名稱之後,我們就可以用getAttribute()方法將它的屬性值拿出來了。例子如下:
例一:
<body>
<p id="p1" customData="pmx">ppp</p>
<script>
var p = document.getElementById("p1");
var pnode = p.getAttributeNode("customData");
console.log(pnode)
</script>
</body>
例二:
//在XX.java(servlet)上寫:
request.setAttribute("message", "失敗");
request.getRequestDispatcher("ngLoad.jsp").forward(request, response);
//在XX.jsp上寫:
<%
String message=(String)request.getAttribute("message");
if (message == "失敗") {
%>
<p style="color:red; margin:0;padding:0;">使用者名稱或密碼錯誤</P>
<%
}
%>
getAttribute和getParameter的區別如下:
1、getAttribute是返回物件,getParameter返回字串。
2、request.getAttribute()方法返回request範圍內存在的物件【當兩個Web元件之間為轉發關係時】,而request.getParameter() 方法是獲取http提交過來的資料【當兩個Web元件之間為連結關係時,如:通過表單和連結傳遞的引數】。
3、與getAttribute()方法對應的有setAttribute()方法,所以說必須先setAttribute設定屬性,才能獲得屬性;
但是沒有與getParameter()相對的setParameter()。