轉載自:http://www.cnblogs.com/happyfans/archive/2015/03/17/4343571.htmljavascript
表現形式 | 所需技術 | |
靜態網頁 | 網頁內容固定,不會更新 | html,css |
動態網頁 | 網頁內容由程序動態顯示,自動更新 | html,css,DB,java/c#/php,javascript,xml,主流的動態網頁腳本(jsp,asp.net,php) |
jdk1.7+tomcat7.0+MyEclipse10。關於MyEclipse的安裝和配置請參見http://blog.sina.com.cn/s/blog_907043b301016jtp.html。Tomcat服務器是Apache Jakarta的開源項目,是Jsp/Servlet容器。安裝Tomcat只須要解壓zip包到指定目錄便可。新建一個環境變量CATALINA_HOME,變量的值是Tomcat的根目錄D:\Program Files (x86)\apache-tomcat-7.0.57。所有的環境變量以下:php
變量名 | 變量值 |
JAVA_HOME | D:\Program Files (x86)\Java\jdk1.7.0_40 |
Path | C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;%JAVA_HOME%\bin;D:\Program Files\Sublime Text 3;D:\Program Files\MySQL\MySQL Utilities 1.3.6\ |
classpath | .;%JAVA_HOME%\lib\rt.jar;%JAVA_HOME%\lib\tools.jar; |
CATALINA_HOME | D:\Program Files (x86)\apache-tomcat-7.0.57 |
以後咱們測試一下Tomcat的首頁:css
進入Tomcat服務器根目錄下面的bin目錄,以管理員方式運行startup.bat,若是運行結果以下就表示Tomcat服務器啓動成功。html
注意:不要關閉這個窗口(關閉窗口就意味着關閉了Tomcat服務器,將其最小化)。java
在瀏覽器地址欄輸入http://localhost:8080/回車獲得以下頁面:
mysql
在項目文件夾中建立一個index.jsp:git
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>手工編寫的第一個java web項目</title> 6 </head> 7 <body> 8 <h1>這是手工編寫的第一個java web項目——jsp</h1> 9 <hr /> 10 </body> 11 </html>
在項目目錄中建立一個WEB-INF目錄拷貝/webapps/examples/WEB-INFO/web.xm到本身項目的/myJspProject/WEB-INFO中,在/myJspProject/WEB-INFO中建立兩個文件夾:classes和lib。最後的項目目錄應該是這樣:web
測試:瀏覽器輸入:http://localhost:8080/myJspProject/index.jsp回車,運行結果以下:sql
解決方法:更改瀏覽器編碼爲指定編碼:數據庫
該目錄是java web應用的安全目錄。所謂安全目錄就是客戶端沒法訪問只有服務端能夠訪問的目錄。其中web.xml是項目部署文件,classes目錄:存放*.class文件,lib目錄存放須要的jar包。例如:咱們在WEB-INF中建立一個test.html,下面咱們經過瀏覽器訪問:
web.xml配置文件能夠配置歡迎頁面默認的歡迎頁面是項目下面的index.jsp,加入咱們須要將項目下的haha.jsp,在/WEB-INF/web.xml的web-app標記中添加如下代碼:
1 <welcome-file-list> 2 <welcome-file>/haha.jsp</welcome-file> 3</welcome-file-list>
運行結果:
注意:若是要使用Eclipse編寫java web應用應該使用Eclipse的J2EE版本。並在Eclipse中配置Tomcat服務器Window-Preference-Server-Runtime Environment-Add,而後在WebContent目錄下新建jsp文件,按下Ctrl+F11(或者在項目中右鍵-Run On Server)就可使用內置瀏覽器訪問創建的網站。
在新建項目以前首先在MyEclipse中配置jre和tomcat。步驟Window-Preference-Java-Install JREs-Add;Window-MyEclipse-Servers-Tomcat(注意設置tomcat的jre並將服務器設置爲Enabled)。
接下來在MyEclipse中啓動Tomcat服務器:
測試首頁http://localhost:8080/證實Tomcat正常啓動,咱們就能夠在MyEclipse中啓動和發佈Web應用程序了。
New一個WebProject會生成如下的目錄結構(默認在WebRoot目錄下有一個index.jsp)。
發佈該WebApp。
該虛擬路徑是能夠修改的項目上右鍵屬性-MyEclipse-Web。
從新部署,瀏覽器須要使用使用http://localhost:8080/hello/index.jsp訪問了。
修改conf目錄下的server.xml的如下標記:
<Connector connectionTimeout="20000" port="8888" protocol="HTTP/1.1" redirectPort="8443"/>
jsp的全名是Java Server Page,是一個簡化的Servlet設計,它實現了在java當中使用html標記。jsp是一種動態網頁技術,符合J2EE標準。jsp和Servlet同樣也是在服務器端執行的。
平臺 | 特色 |
jsp | 跨平臺,安全性高,適合開發大型的、企業級的Web應用、分佈式應用(Hadoop)。例如:1230六、10086.cn、網上銀行 |
asp.net | 簡單易學,安全性和跨平臺性差 |
php | 簡單、高效、成本低、開發週期短,適合中小型企業的Web應用開發(LAMP) |
page指令語法:
<%@ page 屬性1="屬性值" 屬性2="屬性值1,屬性值2" 屬性n="屬性值n"%>
屬性 | 描述 | 默認值 |
language | jsp頁面所使用的腳本語言 | java |
import | 引用腳本語言中所要使用的類文件 | 無 |
contentType | 指定jsp頁面的編碼 | text/html,ISO-8859-1 |
新建一個java web工程默認的jsp頁面開頭有一個page指令:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
默認的編碼是ISO-8859-1,不支持中文,這裏建議使用另外一個屬性contentType。將第一行改成以下:
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
這樣就支持中文了。
page指令的所有屬性以下:
1 <%@page 2 [language="Java"] 3 [extends="package.class"] // 指定JSP頁面編譯所產生的Java類所繼承的父類,或所實現的接口。 4 [import="package.class│package.*,…"] 5 [session="true│false"] 6 [buffer="none│8kb│size kb"] 7 [autoFlush="true│false"] 8 [isThreadSafe="true│false"] 9 [info="text"] 10 [errorPage="relativeURL"] // 指定錯誤處理頁面。由於JSP內建了異常機制支持,因此JSP能夠不處理異常。 11 [contentType="mimeType[;charset=characterSet]"│"text/html;charSet=ISO8859-1"] 12 [isErrorPage="true│false"] // 設置本JSP頁面是否爲錯誤處理程序。 13 %>
注意:除page指令中的import屬性以外,其餘屬性均只能設置一次。
分爲3種:html註釋,jsp註釋,jsp腳本註釋。語法:
1 <!-- html註釋 --> 2 <%-- jsp註釋 --%> 3 <% 4 /*這裏是jsp腳本註釋 有兩種*/ 5 6 //單行註釋 7 8 /*多行註釋*/ 9 %>
例如:
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP 'index.jsp' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 <h1>歡迎你</h1> 25 <!-- 這是html註釋,客戶端可可見 --> 26 <%-- 這是jsp註釋,客戶端不可見 --%> 27 <% 28 /*這裏是jsp腳本註釋 29 有兩種*/ 30 //單行註釋 31 /*多行註釋*/ 32 %> 33 </body> 34 </html>
將項目部署到Tomcat,客戶端用瀏覽器查看源代碼:
在jsp頁面中執行的java代碼。語法:
<% java代碼 %>
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP 'index.jsp' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 <h1>歡迎你</h1> 25 <hr> 26 <% 27 out.println("經過jsp內置對象out對象打印輸出"); 28 %> 29 </body> 30 </html>
jsp頁面中定義變量或者方法。語法:
<%! java代碼 %>
例如:
1 <%! 2 String s = "張三"; //聲明一個String類型的變量 3 int add(int x,int y){ //聲明一個返回值爲int類型的方法 4 return x+y; 5 } 6 %>
jsp頁面中執行的表達式。語法(注意=緊挨着百分號,表達式末尾沒有分號):
<%=表達式 %>
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP 'index.jsp' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 <h1>歡迎你</h1> 25 <hr> 26 <!-- 這是html註釋,客戶端可可見 --> 27 <%! 28 String s = "張三"; //聲明一個String類型的變量 29 int add(int x,int y){ //聲明一個返回值爲int類型的方法 30 return x+y; 31 } 32 %> 33 你好:<%=s %><br> 34 令x=10,y=5,則x+y = <%=add(10, 5) %> 35 </body> 36 </html>
運行結果:
jspService()方法被調用來處理客戶端的請求。對每個請求,JSP引擎建立一個新的線程來處理該請求。若是有多個客戶端同時請求你該jsp文件,則jsp引擎會建立多個線程(每個客戶端請求對應一個線程)。以多線程的方式執行能夠大大下降對系統的資源需求,提升系統的併發量以及縮短服務器的響應時間——可是同時要注意多線程的同步問題。因爲該Servlet常駐內存,因此響應是很是快的。
當頁面沒有被訪問的時候work目錄下沒有相關的Servlet。若是頁面被訪問以後就會在work目錄的對應目錄生成響應的Servlet。如圖:
打開index_jsp.java會看到如下的初始化方法:
而後該Servlet常駐內存,建立線程處理每個客戶端的請求。由每個線程調用_jspService()方法來處理請求。
若是jsp頁面內容發生了改變,jsp引擎就須要從新編譯jsp頁面。咱們修改index.jsp,用瀏覽器從新訪問,則:
1 <%@page import="java.io.IOException"%> 2 <%@ page language="java" import="java.util.*" 3 contentType="text/html; charset=utf-8"%> 4 <% 5 String path = request.getContextPath(); 6 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 7 %> 8 9 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 10 <html> 11 <head> 12 <base href="<%=basePath%>"> 13 14 <title>My JSP 'multiplicationTable.jsp' starting page</title> 15 16 <meta http-equiv="pragma" content="no-cache"> 17 <meta http-equiv="cache-control" content="no-cache"> 18 <meta http-equiv="expires" content="0"> 19 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 20 <meta http-equiv="description" content="This is my page"> 21 22 23 </head> 24 25 <body> 26 <h1>九九乘法表</h1> 27 <h2>表達式的方式打印乘法表</h2> 28 <%! 29 //聲明表達式 30 String printMultiTable(){ 31 StringBuilder s = new StringBuilder(); 32 for(int i=1;i<=9;i++){ 33 for(int j=1;j<=i;j++){ 34 s.append(i+" * "+j+" = "+i*j+"\t"); 35 } 36 s.append("<br />");//追加換行標記,注意不能使用\n 37 } 38 return s.toString(); 39 } 40 %> 41 <%=printMultiTable() //調用表達式 42 %> 43 44 <h2>使用腳本的方式打印九九乘法表</h2> 45 <%! 46 //jsp小腳本 47 void printMultiTable2(JspWriter out) throws IOException{ 48 StringBuilder s = new StringBuilder(); 49 for(int i=1;i<=9;i++){ 50 for(int j =1;j<=i;j++){ 51 s.append(i+" * "+j+" = "+i*j+"\t"); 52 } 53 s.append("<br />"); 54 } 55 out.println(s.toString()); 56 } 57 %> 58 59 <% 60 //調用腳本 61 printMultiTable2(out); 62 %> 63 </body> 64 </html>
運行結果:
JSP內置對象是Web容器建立的一組對象,不須要使用new關鍵字,JSP規範將它們完成了默認初始化(由JSP頁面對應Servlet的_jspService()方法來建立這些實例)。例如打印九九乘法表的jsp小腳本中使用的out對象就是jsp內置對象。
1 <%! 2 //jsp小腳本 3 void printMultiTable2(JspWriter out) throws IOException{ 4 StringBuilder s = new StringBuilder(); 5 for(int i=1;i<=9;i++){ 6 for(int j =1;j<=i;j++){ 7 s.append(i+" * "+j+" = "+i*j+"\t"); 8 } 9 s.append("<br />"); 10 } 11 out.println(s.toString());//這裏的out就是jsp內置對象 12 } 13 %>
JSP一共有9個內置對象,其中經常使用的內置對象有5個,如圖所示:
緩衝區(Buffer)就是內存中用來保存臨時數據的一塊區域。關於緩衝區有一個很形象的例子:好比咱們煮好了飯放在鍋裏,若是咱們一粒一粒地來吃米飯就不知道吃到猴年馬月,拿來一個碗來一碗一碗吃,豈不快哉!這裏的碗就充當了緩衝區的概念。其實IO的本質就是直接操做字節,可是效率太慢因此引入了緩衝區。
out對象是JspWriter類的一個實例——是向客戶端輸出內容的經常使用對象,該對象的經常使用方法:
1 void println(String message); // 向客戶端打印字符串 2 void clear(); // 清除緩衝區內容,若是在flush以後調用會拋出異常 3 void clearBuffer(); // 清除緩衝區內容,若是在flush以後調用不會拋出異常 4 void flush(); // 將緩衝區的內容輸出到客戶端 5 int getBufferSize(); // 返回緩衝區的大小(字節),默認是0 6 int getRemaining(); // 返回緩衝區可用容量 7 boolean isAutoFlush(); // 返回緩衝區滿的時候是自動清空仍是拋出異常 8 void close(); // 關閉輸出流
下面是一個簡單的示例:
1 <h1>JSP的out內置對象</h1> 2 <% 3 //jsp腳本 4 out.println("<h2>靜夜思</h2>"); 5 out.println("李白<br /><br />"); 6 out.println("窗前明月光,<br />"); 7 out.println("疑是地上霜。<br />"); 8 out.println("舉頭望明月,<br />"); 9 out.println("低頭思故鄉。<hr />"); 10 %> 11 <!-- JSP表達式 --> 12 緩衝區大小:<%=out.getBufferSize() %>字節。<br /> 13 剩餘緩衝區(可用緩衝區):<%=out.getRemaining() %>字節。<br /> 14 是否自動清空緩衝區:<%=out.isAutoFlush() %><br />
運行結果:
1 <h1>JSP的out內置對象</h1> 2 <% 3 //jsp腳本 4 out.println("<h2>靜夜思</h2>"); 5 out.println("李白<br /><br />"); 6 out.println("窗前明月光,<br />");
7 out.flush();//將緩衝區中的內容輸出到客戶端
8 out.println("疑是地上霜。<br />"); 9 out.println("舉頭望明月,<br />"); 10 out.println("低頭思故鄉。<hr />"); 11 %> 12 <!-- JSP表達式 --> 13 緩衝區大小:<%=out.getBufferSize() %>字節。<br /> 14 剩餘緩衝區(可用緩衝區):<%=out.getRemaining() %>字節。<br /> 15 是否自動清空緩衝區:<%=out.isAutoFlush() %><br />
若是在第7行強制刷新緩衝區,則輸出的頁面不會有任何變化,僅僅是可用緩衝區的數量變多了而已【由於flush清空了緩衝區】
1 <% 2 //jsp腳本 3 out.println("<h2>靜夜思</h2>"); 4 out.println("李白<br /><br />"); 5 out.println("窗前明月光,<br />"); 6 7 out.flush();//將緩衝區中的內容輸出到客戶端 8 out.clear();//在flush以後調用clear,將會拋出異常 9 10 out.println("疑是地上霜。<br />"); 11 out.println("舉頭望明月,<br />"); 12 out.println("低頭思故鄉。<hr />"); 13 %>
運行結果:
1 <% 2 //jsp腳本 3 out.println("<h2>靜夜思</h2>"); 4 out.println("李白<br /><br />"); 5 out.println("窗前明月光,<br />"); 6 7 out.flush();//將緩衝區中的內容輸出到客戶端 8 out.clearBuffer();//在flush以後調用clearBuffer不會拋出異常 9 10 out.println("疑是地上霜。<br />"); 11 out.println("舉頭望明月,<br />"); 12 out.println("低頭思故鄉。<hr />"); 13 %>
運行結果:
<form name="regForm" action="處理腳本" method="提交方式[post|get]"></form>
1 請輸入用戶名和密碼: 2 <form name = "loginForm" action = "dologin.jsp" method = "get"> 3 用戶名:<input type="text" name="username" value="" maxlength = "15" /><br /> 4 密碼:<input type="password" name="password" maxlength="16" value="" /><br /> 5 <input type="submit" value="提交" /> 6 </form>
處理登陸的動做腳本dologin.jsp僅僅是顯示一句話"登陸成功"。
運行結果:
將用戶登陸表單的get方式改成post。
客戶端的請求被封裝在request對象中,經過它才能瞭解到客戶端的需求,而後作出響應。它是HttpServletRequest對象的實例。request對象具備請求域,即:完成客戶端的請求以前,該對象一直有效。經常使用方法以下:
/* 兩個比較經常使用的方法 */
1 String getParameter(String name); // 返回name指定參數的參數值 2 String[] getParameterValues(String name); // 返回包含name的全部值的數組
3 void setAttribute(String,Object); // 存儲此請求中的屬性 4 String getContentType(); // 返回請求體的MIME類型 5 Stirng getProtocol(); // 返回請求所用的協議和版本號 6 String getServerName(); // 返回接受請求的服務器的主機名 7 int getServerPort(); // 返回服務器接受此請求所用的端口號 8 String getCharacterEncoding(); // 返回字符編碼方式【只能解決post方式的亂碼問題】 9 void setCharacterEncoding(); // 設置請求的字符編碼方式 10 int getContentLength(); // 返回請求體的長度(字節) 11 String getRemoteAddr(); // 返回發送此請求的客戶端IP 12 String getRealPath(String path); // 返回虛擬路徑的真實路徑 13 String request.getContextPath(); // 返回上下文路徑
以用戶註冊頁面爲例(用戶在註冊頁reg.jsp完善信息後提交給request.jsp來處理):
用戶註冊頁reg.jsp
1 請輸入相關信息完成註冊<br /> 2 <form action="request.jsp" name="regForm" method="post"> 3 用戶名:<input type="text" name = "username" /><br /> 4 密碼:<input type="password" name = "password" /><br /> 5 愛好: 6 <input type="checkbox" name = "favorite" value="read"/>讀書 7 <input type="checkbox" name = "favorite" value="music"/>音樂 8 <input type="checkbox" name = "favorite" value="movie"/>電影 9 <input type="checkbox" name = "favorite" value="internet"/>上網<br /> 10 <input type="submit" value="提交" /> 11 </form>
處理用戶註冊頁的request.jsp
1 <h1>request內置對象</h1><br /> 2 3 用戶名:<%=request.getParameter("username") %><br /> 4 密碼:<%=request.getParameter("password") %><hr /> 5 愛好:<br /> 6 <% 7 String[]favorites = request.getParameterValues("favorite"); 8 for(String str:favorites){ 9 out.print(str+" "); 10 } 11 %>
運行結果:
可是以上頁面存在一個問題:假如咱們在用戶名中輸入中文:
這時只要再request.jsp中設置字符集和reg.jsp同樣便可:
1 <h1>request內置對象</h1><br /> 2 <!-- 設置字符集,防止出現中文亂碼 --> 3 <% request.setCharacterEncoding("utf-8"); %>
4 用戶名:<%=request.getParameter("username") %><br /> 5 密碼:<%=request.getParameter("password") %><hr /> 6 愛好:<br /> 7 <% 8 String[]favorites = request.getParameterValues("favorite"); 9 for(String str:favorites){ 10 out.print(str+" "); 11 } 12 %>
除了可使用表單的方式傳遞數據給request對象,也可使用URL傳參的方式傳遞數據給request對象:
reg.jsp
<a href="request.jsp?username=root&password=toor&favorite=read&favorite=internet">測試URL傳參</a>
request.jsp(不變)
1 <h1>request內置對象</h1><br /> 2 <!-- 設置字符集,防止出現中文亂碼 --> 3 <% request.setCharacterEncoding("utf-8"); %> 4 用戶名:<%=request.getParameter("username") %><br /> 5 密碼:<%=request.getParameter("password") %><hr /> 6 愛好:<br /> 7 <% 8 String[]favorites; 9 if((favorites=request.getParameterValues("favorite"))!=null){ 10 for(String str:favorites){ 11 out.print(str+" "); 12 } 13 } 14 %>
運行結果:
若是咱們在URL傳參中傳入了中文數據,一樣會出現亂碼問題:
<a href="request.jsp?username=你好&password=toor&favorite=read&favorite=internet">測試URL傳參</a>
此時經過request.setCharacterEncoding()方法就沒法解決亂碼問題了【一個良好的解決方案是修改tomcat的配置文件server.xml】
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>
向request對象中添加鍵值對:
reg.jsp:
1 請輸入相關信息完成註冊<br /> 2 <form action="request.jsp" name="regForm" method="post"> 3 用戶名:<input type="text" name = "username" /><br /> 4 密碼:<input type="password" name = "password" /><br /> 5 愛好: 6 <input type="checkbox" name = "favorite" value="read"/>讀書 7 <input type="checkbox" name = "favorite" value="music"/>音樂 8 <input type="checkbox" name = "favorite" value="movie"/>電影 9 <input type="checkbox" name = "favorite" value="internet"/>上網<br /> 10 <input type="submit" value="提交" /> 11 </form>
request.jsp
1 <h1>request內置對象</h1><br /> 2 <!-- 設置字符集,防止出現中文亂碼 --> 3 <% request.setCharacterEncoding("utf-8"); %> 4 <% 5 //在request對象中保存一個email屬性 6 request.setAttribute("email","io@gmail.com"); 7 8 %> 9 用戶名:<%=request.getParameter("username") %><br /> 10 密碼:<%=request.getParameter("password") %><hr /> 11 愛好:<br /> 12 <% 13 String[]favorites; 14 if((favorites=request.getParameterValues("favorite"))!=null){ 15 for(String str:favorites){ 16 out.print(str+" "); 17 } 18 } 19 %> 20 <br />郵箱:<%=request.getAttribute("email") %>
運行結果:
1 <h1>request內置對象</h1><br /> 2 <!-- 設置字符集,防止出現中文亂碼 --> 3 <% request.setCharacterEncoding("utf-8"); %> 4 <% 5 //在request對象中保存一個email屬性 6 request.setAttribute("email","io@gmail.com"); 7 8 %> 9 用戶名:<%=request.getParameter("username") %><br /> 10 密碼:<%=request.getParameter("password") %><hr /> 11 愛好:<br /> 12 <% 13 String[]favorites; 14 if((favorites=request.getParameterValues("favorite"))!=null){ 15 for(String str:favorites){ 16 out.print(str+" "); 17 } 18 } 19 %> 20 <br />郵箱:<%=request.getAttribute("email") %> <hr /> 21 請求體的MIME類型:<%=request.getContentType() %><br /> 22 請求體的協議及版本號:<%=request.getProtocol() %><br /> 23 服務器主機名:<%=request.getServerName() %><br /> 24 服務器端口號:<%=request.getServerPort() %><br /> 25 請求的字符編碼:<%=request.getCharacterEncoding() %><br /> 26 請求的文件長度:<%=request.getContentLength() %>字節<br /> 27 請求的客戶端的IP:<%=request.getRemoteAddr() %><br /> 28 請求的真實路徑:<%=request.getRealPath("request.jsp") %><br /> 29 請求的上下文路徑:<%=request.getContextPath() %>
運行結果:
response對象包含了響應客戶請求的相關信息,可是在JSP中不多直接使用到它。它是HttpServletResponse類的實例。response對象具備頁面做用域——即:訪問一個頁面時,該頁面的response只對本次訪問有效,其餘頁面的response對象對當前頁面無效。經常使用方法以下:
1 String getCharacterEncoding(); // 返回響應所用的編碼 2 void setContentType(); // 設置響應的MIME類型 3 PrintWriter getPrintWriter(); // 返回一個能夠向客戶端輸出字符的對象【注意區別於out內置對象】 4 sendRedirect(String location); // 重定向客戶端的請求
response.jsp
1 <%@page import="java.io.PrintWriter"%> 2 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 3 <% 4 response.setContentType("text/html;charset=utf-8");//設置響應的MIME類型 5 6 out.println("<h1>response內置對象</h1><hr />"); 7 8 PrintWriter outer = response.getWriter();//得到輸出流對象 9 outer.println("我是response對象生成的outter對象,在頁面中老是在前面輸出"); 10 %>
運行結果:
運行結果非常奇怪:明明out對象的輸出在代碼中位於前面。可是結果倒是PrintWriter的打印結果在前面,根本緣由就是:PrintWriter的對象的輸出老是在最前面。若是咱們須要讓標題先輸出,可使用內置對象out的flush()方法強制刷新緩衝,向頁面輸出——保證標題出如今最前面。
請求重定向——當用戶請求response.jsp的時候立刻跳轉到login.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> <% response.sendRedirect("login.jsp"); // 請求重定向 %>
3.7請求重定向與請求轉發的區別
若是咱們在response.jsp中使用請求轉發:
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 //請求轉發 4 request.getRequestDispatcher("request.jsp").forward(request, response); 5 %>
運行結果:
Session客戶端與服務器的一次會話。Web中的Session表示用戶在瀏覽某個網站時,從進入網站到瀏覽器關閉所通過的這段時間——也就是用戶瀏覽這個網站所花費的時間。在服務器的內存中保存着不一樣用戶的Session。
session對象的經常使用方法:
1 long getCreationTime(); // 返回session的建立時間 2 String getId(); // 返回session建立時JSP引擎爲它設定的惟一ID號 3 Object setAttribute(String name,Object value); // 使用指定名稱將對象綁定到此會話 4 Object getAttribute(String name); // 返回此會話中的指定名稱綁定在一塊兒的對象,若是沒有對象綁定在該名稱下則返回null 5 String[] getValueNames(); // 返回一個包含此Session全部可用屬性的數組 6 int getMaxInactiveInterval(); // 返回兩次請求間隔多長時間此session被取消【單位:秒】
sesseion_page1.jsp
1 <h1>session內置對象</h1> 2 <h2>session_page1.jsp</h2> 3 <% 4 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 5 String date = sdf.format(new Date(session.getCreationTime())); 6 out.print("session的建立時間:" + date); 7 session.setAttribute("username", "admin"); // 向session中設置屬性 8 %> 9 <br />Session的ID號:<%=session.getId() %><br /> 10 從session中獲取用戶名:<%=session.getAttribute("username") %> 11 12 <a href="session_page2.jsp" target="_blank">以新窗口的方式打開session_page2.jsp</a>
session_page2.jsp
1 <h2>session_page2.jsp</h2> 2 <% 3 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 4 String date = sdf.format(new Date(session.getCreationTime())); 5 out.print("session的建立時間:" + date); 6 %> 7 <br />Session的ID號:<%=session.getId() %><br /> 8 從session中獲取用戶名:<%=session.getAttribute("username") %>
運行結果:
能夠獲取session中保存的屬性集合以及設置session的有效期:
1 <% 2 session.setMaxInactiveInterval(5);//設置session的有效期爲5s 3 4 session.setAttribute("username", "admin"); // 向session中設置屬性 5 session.setAttribute("password", "123456"); 6 session.setAttribute("age", 16); 7 %> 8 9 <% 10 //獲取session中保存的屬性 11 String[]names=session.getValueNames(); 12 if(names!=null){ 13 for(String str:names){ 14 out.print(str+"\t"); 15 } 16 } 17 %>
修改/conf/tomcat-user.xml爲如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <tomcat-users> 3 <role rolename="admin-gui"/> 4 <role rolename="manager-gui"/> 5 <user username="admin" password="admin" roles="admin-gui,manager-gui"></user> 6 </tomcat-users>
在瀏覽器中打開session_page1.jsp而後經過session_page1.jsp的超連接打開session_page2.jsp在後臺管理系統中查看:
若是咱們在session建立以後調用session.invalidate()方法,例如:咱們在session_page1.jsp中這樣寫:
1 <h1>session內置對象</h1> 2 <h2>session_page1.jsp</h2> 3 <% 4 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 5 String date = sdf.format(new Date(session.getCreationTime())); 6 out.print("session的建立時間:" + date); 7 10 session.setAttribute("username", "admin"); // 向session中設置屬性 11 session.setAttribute("password", "123456"); 12 session.setAttribute("age", 16); 13 %> 14 <br />Session的ID號:<%=session.getId() %><hr /> 15 session中保存的屬性有:<br /> 16 <% 17 //獲取session中保存的屬性 18 String[]names=session.getValueNames(); 19 if(names!=null){ 20 for(String str:names){ 21 out.print(str+"\t"); 22 } 23 } 24 session.invalidate();//銷燬session 25 %> 26 <a href = "session_page2.jsp" target = "_blank">點擊在新標籤頁中打開session_page2.jsp</a>
運行結果(不斷刷新瀏覽器):
Session默認session超時是30min設置session對象的超時有兩種方式:
<session-config> <session-timeout>30</session-timeout> </session-config>
1 void setAttribute(String name,Object value); // 指定名稱將對象綁定到此會話 2 Object getAttribute(String name); // 返回此會話中和指定名稱綁定在一塊兒的對象,若是沒有對象綁定在該名稱下則返回null 3 Enumeration getAttributeNames(); // 返回全部可用屬性名的枚舉 4 String getServerInfo(); // 返回JSP(Servlet)引擎名和版本號
1 <h1>application對象</h1> 2 <% 3 //在application中保存3個鍵值對 4 application.setAttribute("city", "北京"); 5 application.setAttribute("zipcode", "10000"); 6 application.setAttribute("email", "io@gmail.com"); 7 %> 8 所在城市:<%=application.getAttribute("city") %><hr> 9 application中存放的屬性有:<br> 10 <% 11 Enumeration attrs = application.getAttributeNames(); 12 while(attrs.hasMoreElements()){ 13 out.print(attrs.nextElement()+"<br>"); 14 } 15 %> 16 <hr> 17 jsp(Servlet)引擎:<%=application.getServerInfo() %><br>
運行效果:
page對象就是指向當前jsp頁面自己(就好像類中的this),是java.lang.Object類的實例,經常使用方法和Object類的方法一致。例如它的toString()方法:
1 <h1>page內置對象</h1> 2 當前頁面的page對象的字符串描述:<br /> 3 <%=page.toString() %>
運行結果:
咱們打開tomcat的work目錄(編譯生成的Servlet目錄)看到它的包結構是org.apache.jsp,在該目錄下有一系列的*_jsp.java和*_jsp.class文件。咱們打開page_jsp.java發現類名就是page_jsp。
1 JspWriter getOut(); // 返回當前客戶端響應被使用的JspWriter流(out) 2 HttpSession getSession(); // 返回當前頁中的HttpSession對象(session) 3 Object getPage(); // 返回當前頁面的Object對象(page) 4 ServletRequest getRequest(); // 返回當前頁面的ServletRequest對象(request) 5 ServletResponse getResponse(); // 返回當前頁面的ServletResponse對象(response) 6 void setAttribute(String name,Object value); // 設置屬性鍵值對 7 Object getAttribute(String name,int scope); // 在指定範圍內取屬性值 8 void forward(String relativeUrlPath); // 將當前頁面重定向到另外一頁面 9 void include(String relativeUrlPath); // 在當前頁面包含另外一文件
咱們在session_page1.jsp中向session中設置了用戶名:
<% session.setAttribute("username", "admin"); %>
如今咱們在pageContext.jsp中取出session中存儲的用戶名(注意要先打開session_page1.jsp):
<h1>pageContext內置對象</h1> 用戶名:<%=pageContext.getSession().getAttribute("username") %>
運行結果:
用pageContext實現頁面跳轉:
<% pageContext.forward("reg.jsp"); %>
運行結果:
新建一個include.jsp(頁面用於向頁面輸出當前的日期):
1 <%@page import="java.text.SimpleDateFormat"%> 2 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 3 <% 4 out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())); 5 %>
下面咱們在pageContext.jsp頁面中包含include.jsp:
1 <h1>pageContext內置對象</h1> 2 用戶名:<%=pageContext.getSession().getAttribute("username") %><hr> 3 4 <!-- 包含其餘頁面 --> 5 <%pageContext.include("include.jsp"); %>
該對象是一個在servlet初始化時,jsp引擎向它傳遞信息時使用的,此信息包含Servlet初始化時所用到的參數(鍵-值對)以及服務器的相關信息(經過傳遞一個ServletContext對象),經常使用方法:
1 ServletContext getServletContext(); // 返回服務器相關信息的ServletContext對象 2 String getInitParameter(String name);// 返回初始化參數的值 3 Enumeration getInitParameterNames(); // 返回Servlet初始化時全部須要參數的枚舉
該對象是一個異常對象,若是一個頁面在運行過程當中出現了異常就會產生這個對象。若是一個JSP頁面須要應用此對象,就必須把isErrorPage設爲true——不然沒法編譯。它其實是java.lang.Throwable的對象,經常使用方法:
1 String getMessage(); // 返回異常的描述信息 2 String toString(); // 返回關於異常的簡短描述信息 3 void printStackTrace(); // 顯示異常及其棧軌跡 4 Throwable FillInStackTrace(); // 重寫異常的執行棧軌跡
首先創建一個會出現異常的頁面exception_text.jsp(並指定處理異常的頁面):
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" errorPage="exception.jsp"%> 2 <!-- 在errorPage中指定處理異常的頁面 --> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>這個頁面確定會出現異常</title> 7 </head> 8 9 <body> 10 <h1>測試異常對象</h1><hr /> 11 <% 12 out.println(100/0);//確定會拋出運行時異常【算術異常】 13 %> 14 </body> 15 </html>
而後創建處理異常的頁面exception.jsp:
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" isErrorPage="true"%> <!-- isErrorPage設爲true表示這是一個異常處理頁面 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'exception.jsp' starting page</title> </head> <body> <h1>Exception內置對象</h1> 異常消息是:<%=exception.getMessage() %><br> 異常的字符串描述:<%=exception.toString() %> </body> </html>
運行結果:
這個案例比較簡單:用戶名和密碼都是admin(沒有使用數據庫),若是用戶名和密碼相符,則頁面跳轉到login_success.jsp【服務器內部轉發】,提示用戶登陸成功;若是用戶登陸失敗,則頁面跳轉到login_failure.jsp【請求重定向】,提示用戶登陸失敗。
整個項目的截圖:
項目地址:https://git.oschina.net/gaopengfei/JSPLogin.git
JavaBean是使用Java語言開發的一個可重用的組件,在JSP的開發中可使用JavaBean減小重複的代碼,使整個JSP代碼的開發更加簡潔。JSP配置JavaBean使用有如下優勢:
1. 將html和java大媽分離,爲往後的維護提供了方便。
2. 能夠利用JavaBean的優勢將經常使用到的程序寫成JavaBean組件,節省開發時間。
簡單JavaBean有如下幾個名詞:
VO:值對象,存放全部的傳遞數據的操做上
POJO:簡單java對象
TO:傳輸對象,必須實現Serializable接口
WEB開發的標準目錄結構
實際上在WEB-INF中的lib和classes目錄就至關於一個默認的classpath(類執行時所須要的一個重要的環境屬性)。當Tomcat啓動以後,WEB-INF/lib和WEB-INF/classes都會自動配置到classpath中。
Javabeans就是符合某種特定規範的的Java類。它的好處有:
一個Javabean要知足4個規範:
例如如下的學生類就是一個Javabean:
1 /** 2 * 這是一個典型的JavaBean 3 */ 4 5 // 1.這是一個共有的類 6 public class Student { 7 // 2.屬性私有 8 private String name; 9 private int age; 10 11 // 3.有共有的無參構造 12 public Student() { 13 } 14 15 // 4.getter和setter 16 public String getName() { 17 return name; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public int getAge() { 25 return age; 26 } 27 28 public void setAge(int age) { 29 this.age = age; 30 } 31 32 }
JavaBean有2種應用方式:
JSP動做元素(action elements),動做元素爲請求處理階段提供信息。動做元素遵循XML元素的語法——有一個元素名的開始標籤,能夠有屬性、可選的內容、與開始標籤匹配的結束標籤。
像使用普通java類同樣,建立javabean實例。在MyEclipse項目的src目錄下新建類Users:
1 package org.po; 2 3 /** 4 * 用戶類-符合Javabean的實際原則 5 */ 6 public class Users { 7 private String username; 8 private String password; 9 10 public Users() { 11 12 } 13 14 public String getUsername() { 15 return username; 16 } 17 18 public void setUsername(String username) { 19 this.username = username; 20 } 21 22 public String getPassword() { 23 return password; 24 } 25 26 public void setPassword(String password) { 27 this.password = password; 28 } 29 30 }
下面咱們在javabean_page1.jsp中使用以上的Javabean:
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <!-- 使用import指令導入Javabean --> 3 <%@ page import="org.po.Users" %> 4 5 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 6 <html> 7 <head> 8 <title>JavaBeans範例</title> 9 </head> 10 11 <body> 12 <h1>使用普通方式建立Javabean的實例</h1> 13 <% 14 //使用普通方式建立JavaBean 15 Users user = new Users(); 16 user.setUsername("admin"); 17 user.setPassword("admin"); 18 %> 19 用戶名:<%=user.getUsername() %><br /> 20 密碼:<%=user.getPassword() %> 21 </body> 22 </html>
運行結果:
<jsp:useBean>用於在jsp頁面中實例化或者在指定範圍內使用JavaBean。基本操做是首先使用id和做用域查找一個現有的對象,若是在指定的做用域中沒有找到具備指定id的對象,那麼它會試圖使用其餘屬性建立一個新實例。語法以下:
<jsp:useBean id="標示符" class="java類名" scope="做用域" />
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <!-- 這裏不須要page指令來導入User類了 --> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>使用useBean動做指令來使用JavaBean</title> 7 </head> 8 9 <body> 10 <h1>使用<jsp:useBean>動做指令來使用JavaBean</h1> 11 <!-- useBean指令 --> 12 <jsp:useBean id="myUsers" class="org.po.Users" scope="page"></jsp:useBean> 13 用戶名:<%=myUsers.getUsername() %><br/> 14 密碼:<%=myUsers.getPassword() %> 15 </body> 16 </html>
運行結果:
上一個jsp頁面中取得的用戶名和密碼都爲null,緣由就是咱們使用僅僅是實例化了Users對象,並無爲其成員變量執行屬性。固然你也可使用setXXX來給已經實例化的JavaBean設置屬性,不過我更推薦使用setProperty指令。
<jsp:setProperty>的主要做用就是給已經實例化的JavaBean的屬性賦值,一共有4種形式:
1 <jsp:setProperty name="JavaBean實例名" property="*" /> <!-- 和表單關聯,所有屬性 --> 2 <jsp:setProperty name="JavaBean實例名" property="JavaBean屬性名" /> <!-- 和表單關聯,指定屬性 --> 3 <jsp:setProperty name="JavaBean實例名" property="JavaBean屬性名" value = "BeanValue" /> <!-- 手工設置 --> 4 <jsp:setProperty name="JavaBean實例名" property="propertyName" param="request對象中的參數名"/> <!-- 和request參數關聯,URL傳參 -->
方式一:【表單內容的自動所有匹配】
新建一個用戶登陸表單login.jsp:
1 <form action="dologin.jsp" method="post" name="loginForm"> 2 用戶名:<input type="text" name="username"/><br /> 3 密碼:<input type="password" name="password" /> 4 <input type="submit" value="提交" /> 5 </form>
處理用戶登陸的頁面dologin.jsp
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>用戶登陸處理頁面</title> 12 </head> 13 14 <body> 15 16 <!-- 實例化javaBean對象 --> 17 <jsp:useBean id="myUsers" class="org.po.Users"></jsp:useBean> 18 19 <h1>setPerpority動做元素</h1><hr /> 20 21 <!-- 根據表單自動匹配全部的屬性並設置 --> 22 <jsp:setProperty property="*" name="myUsers"/> 23 用戶名:<%=myUsers.getUsername() %><br> 24 密碼:<%=myUsers.getPassword() %> 25 26 </body> 27 </html>
運行結果:
這實際上以依靠表單中的name屬性來匹配javabean中的成員變量。例如:在用戶登陸表單中input標記的屬性有一個name="username",那麼使用這種自動匹配的方式就會把這個username與javabean中的屬性挨個查找,若是找到了就爲這個字段設定相應的值——換言之:表單中的name屬性要和要和javabean中的屬性對應相同。
方式二:部分匹配表單的屬性(dologin.jsp):
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>用戶登陸處理頁面</title> 12 </head> 13 14 <body> 15 16 <!-- 實例化javaBean對象 --> 17 <jsp:useBean id="myUsers" class="org.po.Users"></jsp:useBean> 18 19 <h1>setPerpority動做元素</h1><hr /> 20 21 <!-- 根據表單匹配部分屬性 --> 22 <jsp:setProperty property="username" name="myUsers"/> 23 用戶名:<%=myUsers.getUsername() %><br> 24 密碼:<%=myUsers.getPassword() %> 25 26 </body> 27 </html>
運行結果:
僅僅匹配了用戶名屬性,因爲密碼屬性沒有匹配,因此爲null。這種方式也要注意表單的name屬性要和javabean的屬性相同。
方式三:手工給javabean的屬性賦值——與表單無關(dologin.jsp):
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>用戶登陸處理頁面</title> 12 </head> 13 14 <body> 15 16 <!-- 實例化javaBean對象 --> 17 <jsp:useBean id="myUsers" class="org.po.Users"></jsp:useBean> 18 19 <h1>setPerpority動做元素</h1><hr /> 20 21 <!-- 與表單無關,經過手工給javabean的屬性賦值 --> 22 <jsp:setProperty property="username" name="myUsers" value="root"/> 23 <jsp:setProperty property="password" name="myUsers" value="123456"/> 24 用戶名:<%=myUsers.getUsername() %><br> 25 密碼:<%=myUsers.getPassword() %> 26 27 </body> 28 </html>
方式四(經過URL傳參的方式給javabean賦值):
login.jsp:
<a href="dologin.jsp?id=root&sn=123456">經過url傳參的方式給javabean的屬性賦值</a>
dologin.jsp:
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>用戶登陸處理頁面</title> 12 </head> 13 14 <body> 15 16 <!-- 實例化javaBean對象 --> 17 <jsp:useBean id="myUsers" class="org.po.Users"></jsp:useBean> 18 19 <h1>setPerpority動做元素</h1><hr /> 20 21 <!-- 經過URL傳參的方式給javabean屬性賦值--> 22 <jsp:setProperty property="username" name="myUsers" param="id"/> 23 <jsp:setProperty property="password" name="myUsers" param="sn"/> 24 用戶名:<%=myUsers.getUsername() %><br> 25 密碼:<%=myUsers.getPassword() %> 26 27 </body> 28 </html>
運行結果:
<jsp:getProperty>獲取指定JavaBean對象的屬性值【String類型】。語法:
<jsp:getProperty name="JavaBean實例名" property="屬性名" />
前面的例子已經經過URL傳遞參數的方式指定了javabean的屬性值,如今經過getProperty的方式得到javabean的屬性值:
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 <title>用戶登陸處理頁面</title> 12 </head> 13 14 <body> 15 16 <!-- 實例化javaBean對象 --> 17 <jsp:useBean id="myUsers" class="org.po.Users"></jsp:useBean> 18 19 <h1>setPerpority動做元素</h1><hr /> 20 21 <!-- 經過URL傳參的方式給javabean屬性賦值--> 22 <jsp:setProperty property="username" name="myUsers" param="id"/> 23 <jsp:setProperty property="password" name="myUsers" param="sn"/> 24 25 <!-- 經過getter得到javabean的屬性值 --> 26 <%-- 27 用戶名:<%=myUsers.getUsername() %><br> 28 密碼:<%=myUsers.getPassword() %> 29 --%> 30 31 <!-- 經過getProperty得到javabean的屬性值 --> 32 用戶名:<jsp:getProperty property="username" name="myUsers"/><br /> 33 密碼:<jsp:getProperty property="password" name="myUsers"/> 34 </body> 35 </html>
運行結果:
使用useBean的scope屬性能夠指定javabean的做用域。
1 page // 當前頁面有效,能夠經過PageContext.getAttribute()得到JavaBean對象。 2 request // 同一個請求有效,可經過HttpRequest.getAttibute()方法得到JavaBean對象。 3 session // 同一個session有效,可經過HttpSession.getAttribute()方法得到JavaBean對象。 4 application // 同一個application有效,可經過application.getAttribute()方法得到JavaBean對象。
下面是一個簡單的測試4個做用範圍的示例:
dolog.jsp以URL傳參的方式爲javabean指定屬性值:
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>用戶登陸處理頁面</title> 6 </head> 7 8 <body> 9 10 <!-- 實例化javaBean對象,並制定做用域爲application --> 11 <jsp:useBean id="myUsers" class="org.po.Users" scope="application"></jsp:useBean> 12 13 <h1>setPerpority動做元素</h1><hr /> 14 15 <!-- 經過URL傳參的方式給javabean的屬性賦值--> 16 <jsp:setProperty property="username" name="myUsers" param="id"/> 17 <jsp:setProperty property="password" name="myUsers" param="sn"/> 18 19 <a href="test_scope.jsp">測試javabean的4個做用域範圍</a> 20 21 </body> 22 </html>
dologin.jsp中有一個跳轉連接test_scope.jsp用於跳轉頁面,下面是test_scope.jsp。
1 <%@page import="org.po.Users"%> 2 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 3 4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 5 <html> 6 <head> 7 <title>檢驗useBean的4個做用域</title> 8 </head> 9 10 <body> 11 <h1>檢驗useBean的4個做用域</h1><hr> 12 13 <jsp:useBean id="myUsers" class="org.po.Users" scope="application"></jsp:useBean> 14 <!-- 經過getProperty獲取javabean屬性值 --> 15 <h2>用jsp動做元素獲取javabean的屬性值</h2> 16 用戶名:<jsp:getProperty property="username" name="myUsers"/><br /> 17 密碼:<jsp:getProperty property="password" name="myUsers"/><hr> 18 19 <!-- 經過內置對象獲取javabean的屬性值 --> 20 <h2>經過內置對象獲取javabean的屬性值</h2> 21 用戶名:<%=((Users)application.getAttribute("myUsers")).getUsername() %><br> 22 密碼:<%=((Users)application.getAttribute("myUsers")).getPassword() %> 23 </body> 24 </html>
按照上面的例子分別將scope換成session、request和page獲得以下以下結果:javabean的做用域範圍從大到小依次是:application、session、request、page。
JavaBean雖然使用了<jsp:useBean>標籤進行建立,可是其操做仍然依靠的是4種屬性範圍。若是一個JavaBean再也不使用的話,則可使用對應的removeAttribute()方法進行刪除。
1 pageContext.removeAttribute(JavaBean名稱) // 刪除page範圍內的JavaBean 2 request.removeAttribute(JavaBean名稱) // 刪除request範圍內的JavaBean 3 session.removeAttribute(JavaBean名稱) // 刪除session範圍內的JavaBean 4 application.removeAttribute(JavaBean名稱) // 刪除application範圍內的JavaBean
1 package org.gpf; 2 3 public class Count { 4 5 private int count = 0; 6 7 public Count() { 8 System.out.println("======== 一個新的Count實例產生了 ========"); 9 } 10 11 public int getCount() { 12 return ++count; 13 } 14 15 }
1 <%@ page language="java" contentType="text/html; charset=utf-8"%> 2 <!-- 建立JavaBean,指定做用域爲session --> 3 <jsp:useBean id="c" class="org.gpf.Count" scope="session"></jsp:useBean> 4 count = <jsp:getProperty property="count" name="c"/> 5 <% 6 session.removeAttribute("c"); // 刪除javaBean 7 %>
咱們原本設置的是session範圍內的JavaBean,刷新頁面不該該有新的JavaBean產生,可是咱們在最後使用了session.removeAttribute()方法將建立的JavaBean刪除了,於是每次請求都會產生新的JavaBean。
Model 1模型出現之前,整個Web應用幾乎所有由JSP頁面組成,JSP頁面接收處理客戶端請求,對請求處理後直接響應。這樣作的一個弊端就是:在界面層(JSP頁面)中充斥着大量的業務邏輯代碼和數據訪問層的代碼,Web程序的可擴展性和可維護性很是差。
JavaBean的出現可使得能夠在JSP頁面中調用JavaBean封裝的數據或者業務邏輯代碼,大大提高了程序的可維護性。下面的這張圖簡單描述了Model 1.
模型一體現了一種Web應用的分層架構。
首先創建一個用戶類Users(javabean):
1 package org.po; 2 3 /** 4 * 用戶類-javabean 5 */ 6 public class Users { 7 private String username; 8 private String passwordString; 9 10 public Users() { 11 } 12 13 public String getUsername() { 14 return username; 15 } 16 17 public void setUsername(String username) { 18 this.username = username; 19 } 20 21 public String getPasswordString() { 22 return passwordString; 23 } 24 25 public void setPasswordString(String passwordString) { 26 this.passwordString = passwordString; 27 } 28 29 }
下面編寫一個用戶業務邏輯類:
1 package org.dao; 2 3 import org.po.Users; 4 5 /** 6 * 用戶的業務邏輯類 7 */ 8 public class UsersDAO { 9 public boolean isUserLogin(Users users) { 10 return "admin".equals(users.getUsername()) 11 && "admin".equals(users.getPassword()); 12 } 13 }
業務邏輯處理的頁面dologin.jsp:
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <!-- 引入實體類Users --> 4 <jsp:useBean id="loginUser" class="org.po.Users"></jsp:useBean> 5 <!-- 引入業務邏輯類UsersDAO --> 6 <jsp:useBean id="userDAO" class="org.dao.UsersDAO"></jsp:useBean> 7 8 <!-- 爲javaBean loginUser設置屬性,使用表單自動設置所有的值 --> 9 <jsp:setProperty property="*" name="loginUser"/> 10 11 <!-- 調用業務邏輯代碼 --> 12 <% 13 request.setCharacterEncoding("utf-8");//防止中文亂碼 14 if(userDAO.isUserLogin(loginUser)){ 15 //若是用戶登陸成功則向session中設置用戶名和密碼 16 session.setAttribute("username", loginUser.getUsername()); 17 session.setAttribute("password", loginUser.getPassword()); 18 //請求轉發 19 request.getRequestDispatcher("login_success.jsp").forward(request, response); 20 }else{ 21 //重定向 22 response.sendRedirect("login_failure.jsp"); 23 } 24 %>
項目地址:https://git.oschina.net/gaopengfei/loginDemoByModel1.git
該項目中主要的修改的dologin.jsp在該頁面中沒有使用request對象直接從表單中讀出數據,而是從javabean中取出屬性,而且用戶合法性的判斷也放在了javabean中很好的體現了Web的分層思想(邏輯與頁面分離)。
http的無狀態性是指:當瀏覽器發送請求給服務器的時候,服務器響應客戶端的請求。可是當瀏覽器再次發送請求給服務器的時候,服務器並不知道它就是剛剛的那個瀏覽器。——服務器不會記住你。爲了保存用戶的狀態有兩種機制:
Cookie是Web服務器保存在客戶端的一系列文本信息。
在JSP頁面中建立和使用Cookie
1 Cookie newCookie = new Cookie(String key,Object value); // 建立Cookie對象 2 response.add(newCookie); // 寫入Cookie對象 3 Cookie[] cookies = request.getCookies(); // 讀取Cookie對象
Cooike對象的經常使用方法:
1 void setMaxAge(int expiry); // 設置cookie的有效期【秒】 2 void setValue(String value);// 對已經實例化的cookie對象賦值 3 String getName(); // 得到cookie的名稱 4 String getValue(); // 得到cookie的值 5 int getMaxAge(); // 得到cookie的有效時間【秒】
注意:以上方法中的setValue(String value)和String getValue()方法的返回值都是字符串類型——由於Cookie本質上就是一個字符串存儲在客戶端,不管對它存值仍是取值都應該是字符串類型。
實現記憶用戶名和密碼的功能。
用戶登錄頁login.jsp
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>用戶登陸</title> 7 </head> 8 9 <body> 10 <% 11 /*得到Cookie中保存的用戶名和密碼*/ 12 String username = ""; 13 String password = ""; 14 15 Cookie[]cookies = request.getCookies(); 16 if(cookies!=null&&cookies.length>0){ 17 for(Cookie c:cookies){ 18 if(c.getName().equals("username")){ 19 username = c.getValue(); 20 } 21 if(c.getName().equals("password")){ 22 password = c.getValue(); 23 } 24 } 25 } 26 %> 27 28 請輸入用戶名和密碼: 29 <br /> 30 <form action="dologin.jsp" name="loginForm" method="post"> 31 用戶名:<input type="text" name="username" value="<%= username%>" /><br /> 32 密碼:<input type="password" name="password" value="<%= password%>"><br /> 33 <input type="checkbox" checked="checked" name="isUseCookie"> 34 十天內記住我<br /> <input type="submit" value="登陸" /> 35 </form> 36 37 </body> 38 </html>
處理用戶登陸的頁面dologin.jsp
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>處理用戶登陸</title> 7 </head> 8 9 <body> 10 <h1>登陸成功!</h1> 11 <hr /> 12 <% 13 //判斷用戶是否選擇了記住密碼 14 String[] isUseCookie = request.getParameterValues("isUseCookie"); 15 if(isUseCookie!=null&&isUseCookie.length>0){ 16 /*把用戶名和密碼保存在Cookie對象中*/ 17 String username = request.getParameter("username"); 18 String password = request.getParameter("password"); 19 //建立2個Cookie對象 20 Cookie usernameCookie = new Cookie("username",username); 21 Cookie passwordCookie = new Cookie("password",password); 22 usernameCookie.setMaxAge(3600*24*10);//設置cookie生存期10天 23 passwordCookie.setMaxAge(3600*24*10); 24 25 //在客戶端保存Cookie對象,須要依賴response對象的addCookie方法 26 response.addCookie(usernameCookie); 27 response.addCookie(passwordCookie); 28 }else{ 29 /*使已經保存的cookie對象失效*/ 30 Cookie[]cookies = request.getCookies();//獲得客戶端保存的cookie 31 if(cookies!=null&&cookies.length>0){ 32 //遍歷Cookie數組 33 for(Cookie c:cookies){ 34 if(c.getName().equals("username")||c.getName().equals("password")){ 35 c.setMaxAge(0);//設置Cookie的有效期是0,讓其立刻失效 36 response.addCookie(c);//從新向客戶端保存Cookie 37 } 38 } 39 } 40 } 41 %> 42 <a href="users.jsp">點擊查看用戶信息</a> 43 </body> 44 </html>
用戶信息顯示頁users.jsp
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>用戶信息顯示</title> 7 </head> 8 9 <body> 10 <h1>用戶信息</h1> 11 <hr /> 12 <% 13 /*得到Cookie中保存的用戶名和密碼*/ 14 String username = ""; 15 String password = ""; 16 17 Cookie[]cookies = request.getCookies(); 18 if(cookies!=null&&cookies.length>0){ 19 for(Cookie c:cookies){ 20 if(c.getName().equals("username")){ 21 username = c.getValue(); 22 } 23 if(c.getName().equals("password")){ 24 password = c.getValue(); 25 } 26 } 27 } 28 %> 29 用戶名:<%=username %><br /> 密碼:<%=password %> 30 </body> 31 </html>
該項目通常狀況下可以正常運行,可是當咱們輸入中文用戶名的時候,服務器會拋出一個500的錯誤。要解決這個問題就須要依靠java網絡包中的URLEncoder和URLDecoder,除此以外不要忘記了在每次使用request對象以前首先要設置request對象的編碼方式。完整的代碼以下:
login.jsp
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <%@page import="java.net.URLDecoder"%> 4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 5 <html> 6 <head> 7 <title>用戶登陸</title> 8 </head> 9 10 <body> 11 <% 12 /*得到Cookie中保存的用戶名和密碼*/ 13 String username = ""; 14 String password = ""; 15 16 request.setCharacterEncoding("utf-8"); 17 Cookie[]cookies = request.getCookies(); 18 if(cookies!=null&&cookies.length>0){ 19 for(Cookie c:cookies){ 20 if (c.getName().equals("username")) { 21 username = URLDecoder.decode(c.getValue(), "utf-8"); 22 } 23 if (c.getName().equals("password")) { 24 password = URLDecoder.decode(c.getValue(), "utf-8"); 25 } 26 } 27 } 28 %> 29 30 請輸入用戶名和密碼: 31 <br /> 32 <form action="dologin.jsp" name="loginForm" method="post"> 33 用戶名:<input type="text" name="username" value="<%= username%>" /><br /> 34 密碼:<input type="password" name="password" value="<%= password%>"><br /> 35 <input type="checkbox" checked="checked" name="isUseCookie"> 36 十天內記住我<br /> <input type="submit" value="登陸" /> 37 </form> 38 39 </body> 40 </html>
dologin.jsp
1 <%@page import="java.net.URLEncoder"%> 2 <%@ page language="java" import="java.util.*" 3 contentType="text/html; charset=utf-8"%> 4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 5 <html> 6 <head> 7 <title>處理用戶登陸</title> 8 </head> 9 10 <body> 11 <h1>登陸成功!</h1> 12 <hr /> 13 <% 14 //判斷用戶是否選擇了記住密碼 15 request.setCharacterEncoding("utf-8"); 16 String[] isUseCookie = request.getParameterValues("isUseCookie"); 17 if (isUseCookie != null && isUseCookie.length > 0) { 18 /*把用戶名和密碼保存在Cookie對象中*/ 19 //獲得登陸表單中的內容並編碼 20 String username = URLEncoder.encode( 21 request.getParameter("username"), "utf-8"); 22 String password = URLEncoder.encode( 23 request.getParameter("password"), "utf-8"); 24 //建立2個Cookie對象 25 Cookie usernameCookie = new Cookie("username", username); 26 Cookie passwordCookie = new Cookie("password", password); 27 usernameCookie.setMaxAge(3600 * 24 * 10);//設置cookie生存期10天 28 passwordCookie.setMaxAge(3600 * 24 * 10); 29 30 //在客戶端保存Cookie對象,須要依賴response對象的addCookie方法 31 response.addCookie(usernameCookie); 32 response.addCookie(passwordCookie); 33 } else { 34 /*使已經保存的cookie對象失效*/ 35 Cookie[] cookies = request.getCookies();//獲得客戶端保存的cookie 36 if (cookies != null && cookies.length > 0) { 37 //遍歷Cookie數組 38 for (Cookie c : cookies) { 39 if (c.getName().equals("username") 40 || c.getName().equals("password")) { 41 c.setMaxAge(0);//設置Cookie的有效期是0,讓其立刻失效 42 response.addCookie(c);//從新向客戶端保存Cookie 43 } 44 } 45 } 46 } 47 %> 48 <a href="users.jsp">點擊查看用戶信息</a> 49 </body> 50 </html>
users.jsp
1 <%@page import="java.net.URLDecoder"%> 2 <%@ page language="java" import="java.util.*" 3 contentType="text/html; charset=utf-8"%> 4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 5 <html> 6 <head> 7 <title>用戶信息顯示</title> 8 </head> 9 10 <body> 11 <h1>用戶信息</h1> 12 <hr /> 13 <% 14 /*得到Cookie中保存的用戶名和密碼*/ 15 String username = ""; 16 String password = ""; 17 18 request.setCharacterEncoding("utf-8"); 19 Cookie[] cookies = request.getCookies(); 20 if (cookies != null && cookies.length > 0) { 21 for (Cookie c : cookies) { 22 if (c.getName().equals("username")) { 23 username = URLDecoder.decode(c.getValue(), "utf-8"); 24 } 25 if (c.getName().equals("password")) { 26 password = URLDecoder.decode(c.getValue(), "utf-8"); 27 } 28 } 29 } 30 %> 31 用戶名:<%=username%><br /> 密碼:<%=password%> 32 </body> 33 </html>
修正後的項目就支持中文用戶名了。Cookie與Session的區別是Cookie存放於瀏覽器中,瀏覽器關閉後再打開,已經保存的cookie仍是存在。
Session | Cookie | |
保存位置 | 服務端保存用戶信息 | 客戶端保存用戶信息 |
保存類型 | Session中保存的是Object類型 | Cookie中保存的是String類型 |
生命週期 | 會話結束,則存儲的數據銷燬 | Cookie可長期保存在客戶端 |
重要性 | 保存重要信息 | 保存不重要信息 |
語法:
<%@ include file="URL"%>
例如咱們要在include_command.jsp中包含date.jsp的頁面——即:在include_command中顯示date.jsp的內容:
date.jsp
1 <%@page import="java.text.SimpleDateFormat"%> 2 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 3 <% 4 out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())); 5 %>
include_command.jsp
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>在該頁面中使用include指令將剛剛寫的date.jsp包含進來</title> 6 </head> 7 8 <body> 9 <h1>在該頁面中使用include指令將剛剛寫的date.jsp包含進來</h1><hr /> 10 <%@include file="date.jsp" %> 11 </body> 12 </html>
運行結果:
include動做其實是JSP動做標籤,語法:
<jsp:include page="URL" flush="true|false" />
其中page屬性是須要包含的頁面的URL,而flush屬性制定了被包含的頁面是否從緩衝區中讀取。
demo:使用include動做在include_action.jsp中包含date.jsp
include_action.jsp
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>include動做</title> 6 </head> 7 8 <body> 9 <h1>在該頁面中使用include動做將剛剛寫的date.jsp包含進來</h1><hr /> 10 <jsp:include page="date.jsp" flush="false"></jsp:include> 11 </body> 12 </html>
使用include動做和include指令在jsp頁面的執行效果上沒有任何區別。
在Tomcat服務器的work目錄中刪除剛剛發佈的工程:
先訪問include_command.jsp
work目錄生成如下內容:
打開include_005fcommand_jsp.java發如今它的源代碼中有date.jsp的源代碼:
out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
include指令主頁面和被包含的頁面轉換成了同一個Servlet。
在Tomcat的work目錄中刪除編譯生成的Servlet,訪問include_action.jsp生成如下文件:
打開include_005faction_jsp.java發現源代碼中並無包含date.jsp的源代碼,而是由下面的一條代碼將date.jsp的輸出結果包含到該jsp頁面:
// 該語句至關於調用date.jsp,並將date.jsp的輸出結果返回給該頁面 org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "date.jsp", out, false);
服務器內部轉發指令,語法:
1 <jsp:forward page="URL" /> 2 3 // 至關於 4 request.getRequestDispatcher("url").forward(request,response);
例如:在登錄頁中將用戶的表單處理交給forward_action.jsp頁面處理,forward_action.jsp將該請求經過forward動做轉發給users.jsp,users.jsp從request對象中取得用戶名和密碼給予顯示:
login.jsp
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>用戶登陸</title> 7 </head> 8 9 <body> 10 請輸入用戶名和密碼: 11 <br /> 12 <form action="forward_action.jsp" name="loginForm" method="post"> 13 用戶名:<input type="text" name="username" /><br /> 14 密碼:<input type="password" name="password" /><br /> 15 <input type="submit" value="登陸" /> 16 </form> 17 </body> 18 </html>
forward_action.jsp
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>forward動做</title> 6 </head> 7 8 <body> 9 <h1>該頁面處理用戶提交的表單信息</h1> 10 <h2>forward動做</h2> 11 <jsp:forward page="users.jsp"></jsp:forward> 12 <!-- 上面這條語句和下面的這條語句至關 --> 13 <%-- 14 request.getRequestDispatcher("users.jsp").forward(request, response); 15 --%> 16 </body> 17 </html>
users.jsp
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>用戶信息顯示</title> 7 </head> 8 9 <body> 10 <h1>用戶信息</h1> 11 <hr /> 12 <% 13 request.setCharacterEncoding("utf-8"); 14 15 String username = ""; 16 String password = ""; 17 if(request.getParameter("username")!=null){ 18 username = request.getParameter("username"); 19 } 20 if(request.getParameter("password")!=null){ 21 password = request.getParameter("password"); 22 } 23 %> 24 用戶名:<%=username %><br /> 密碼:<%=password %> 25 </body> 26 </html>
運行結果:
語法:
1 <jsp:param name="參數名" value="參數名" /> 2 <!-- 該動做經常做爲<jsp:forward>的子標籤,和它一塊兒使用 -->
用戶將提交的表單交給dologin.jsp處理,dologin.jsp經過forward動做把請求轉發給users.jsp(並人爲添加表單中沒有的內容:郵箱,修改表單中提交的用戶名爲root),users.jsp經過request.getParamer()方法得到用戶名、密碼、郵箱並予以顯示:
login.jsp
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>用戶登陸</title> 7 </head> 8 9 <body> 10 請輸入用戶名和密碼: 11 <br /> 12 <form action="dologin.jsp" name="loginForm" method="post"> 13 用戶名:<input type="text" name="username" /><br /> 14 密碼:<input type="password" name="password" /><br /> 15 <input type="submit" value="登陸" /> 16 </form> 17 </body> 18 </html>
dologin.jsp
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <jsp:forward page="users.jsp"> 3 <jsp:param value="io@gmail.com" name="email"/> 4 <jsp:param value="root" name="username"/> 5 </jsp:forward>
users.jsp
1 <%@ page language="java" import="java.util.*" 2 contentType="text/html; charset=utf-8"%> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>用戶信息顯示</title> 7 </head> 8 9 <body> 10 <h1>用戶信息</h1> 11 <hr /> 12 <% 13 request.setCharacterEncoding("utf-8"); 14 15 String username = ""; 16 String password = ""; 17 String email = ""; 18 if(request.getParameter("username")!=null){ 19 username = request.getParameter("username"); 20 } 21 if(request.getParameter("password")!=null){ 22 password = request.getParameter("password"); 23 } 24 if(request.getParameter("email")!=null){ 25 email = request.getParameter("email"); 26 } 27 %> 28 用戶名:<%=username %><br /> 密碼:<%=password %><br>郵箱:<%=email %> 29 </body> 30 </html>
效果圖:
該項目使用Model1(JSP+JavaBean)使用Cookie機制實現。該項目使用到了數據庫(數據庫中存放了商品表)。實現步驟以下:
DB-->JavaBean-->JSP。項目的目錄結構:
1、實現DBHelper類:
該類的主要做用是取得數據庫的鏈接並關閉相關資源。
1 package util; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 9 public class DBHelper { 10 private static final String DRIVER = "com.mysql.jdbc.Driver"; 11 private static final String URL = "jdbc:mysql://localhost:3306/shopping?useUnicode=true&characterEncoding=UTF-8"; 12 private static final String USER = "root"; 13 private static final String PASSWORD = "mysqladmin"; 14 15 private static Connection coon = null;// DB鏈接對象 16 17 /** 靜態代碼塊加載DB驅動 */ 18 static { 19 try { 20 Class.forName(DRIVER); 21 } catch (ClassNotFoundException e) { 22 e.printStackTrace(); 23 } 24 } 25 26 /** Singleton設計模式返回DB鏈接對象 */ 27 public static Connection getConnection() throws SQLException { 28 if (coon == null) { 29 coon = DriverManager.getConnection(URL, USER, PASSWORD); 30 return coon; 31 } 32 return coon; 33 } 34 35 /** 清理資源-關閉DB結果集、釋放語句對象 */ 36 public static void relsaseResource(ResultSet rs,PreparedStatement pstmt){ 37 // 釋放結果集 38 if (rs != null) { 39 try { 40 rs.close(); 41 rs = null; 42 } catch (SQLException e) { 43 e.printStackTrace(); 44 } 45 } 46 // 釋放語句對象 47 if (pstmt != null) { 48 try { 49 pstmt.close(); 50 pstmt = null; 51 } catch (SQLException e) { 52 e.printStackTrace(); 53 } 54 } 55 } 56 57 /** 測試DB鏈接 */ 58 public static void main(String[] args) { 59 try { 60 Connection connection = DBHelper.getConnection(); 61 if(connection!=null){ 62 System.out.println("數據庫鏈接成功!"); 63 }else { 64 System.out.println("數據庫鏈接異常!"); 65 } 66 } catch (SQLException e) { 67 e.printStackTrace(); 68 } 69 } 70 }
若是shopping數據庫沒有建立可能會拋出異常只須要執行:
create database shopping;
2、商品實體類的設計:
在建立實體類以前先創建好數據庫表:
數據庫腳本:items.sql
1 /* 2 Navicat MySQL Data Transfer 3 4 Source Server : MySQL50 5 Source Server Version : 50067 6 Source Host : localhost:3306 7 Source Database : shopping 8 9 Target Server Type : MYSQL 10 Target Server Version : 50067 11 File Encoding : 65001 12 13 Date: 2014-08-27 12:12:31 14 */ 15 16 SET FOREIGN_KEY_CHECKS=0; 17 18 -- ---------------------------- 19 -- Table structure for items 20 -- ---------------------------- 21 DROP TABLE IF EXISTS `items`; 22 CREATE TABLE `items` ( 23 `id` int(11) NOT NULL auto_increment, 24 `name` varchar(50) default NULL, 25 `city` varchar(50) default NULL, 26 `price` int(11) default NULL, 27 `number` int(11) default NULL, 28 `picture` varchar(500) default NULL, 29 PRIMARY KEY (`id`) 30 ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; 31 32 -- ---------------------------- 33 -- Records of items 34 -- ---------------------------- 35 INSERT INTO `items` VALUES ('1', '沃特籃球鞋', '佛山', '180', '500', '001.jpg'); 36 INSERT INTO `items` VALUES ('2', '安踏運動鞋', '福州', '120', '800', '002.jpg'); 37 INSERT INTO `items` VALUES ('3', '耐克運動鞋', '廣州', '500', '1000', '003.jpg'); 38 INSERT INTO `items` VALUES ('4', '阿迪達斯T血衫', '上海', '388', '600', '004.jpg'); 39 INSERT INTO `items` VALUES ('5', '李寧文化衫', '廣州', '180', '900', '005.jpg'); 40 INSERT INTO `items` VALUES ('6', '小米3', '北京', '1999', '3000', '006.jpg'); 41 INSERT INTO `items` VALUES ('7', '小米2S', '北京', '1299', '1000', '007.jpg'); 42 INSERT INTO `items` VALUES ('8', 'thinkpad筆記本', '北京', '6999', '500', '008.jpg'); 43 INSERT INTO `items` VALUES ('9', 'dell筆記本', '北京', '3999', '500', '009.jpg'); 44 INSERT INTO `items` VALUES ('10', 'ipad5', '北京', '5999', '500', '010.jpg');
在MySQL中查詢:
創建實體類(Items):也就是javabean其屬性與DB中的各個字段一一對應。
1 package entity; 2 3 /** 4 * 商品類(與DB中的表名一致)-javabean 屬性和DB中表的字段徹底一致 5 */ 6 public class Items { 7 private int id; 8 private String name; 9 private String city; 10 private int price; 11 private int number; 12 private String picture; 13 14 public Items() { 15 } 16 17 public int getId() { 18 return id; 19 } 20 21 public void setId(int id) { 22 this.id = id; 23 } 24 25 public String getName() { 26 return name; 27 } 28 29 public void setName(String name) { 30 this.name = name; 31 } 32 33 public String getCity() { 34 return city; 35 } 36 37 public void setCity(String city) { 38 this.city = city; 39 } 40 41 public int getPrice() { 42 return price; 43 } 44 45 public void setPrice(int price) { 46 this.price = price; 47 } 48 49 public int getNumber() { 50 return number; 51 } 52 53 public void setNumber(int number) { 54 this.number = number; 55 } 56 57 public String getPicture() { 58 return picture; 59 } 60 61 public void setPicture(String picture) { 62 this.picture = picture; 63 } 64 65 }
3、實現業務邏輯類(數據訪問層DAO)
該類須要完成的功能:
分析:
1.在index.jsp中咱們須要展現全部的商品信息。——得到全部商品
2.當用戶點擊任意一種商品後會將id經過URL傳遞給details.jsp,而在details.jsp中咱們須要——根據id得到對應商品。
3.根據Cookie傳入的字符串得到最近瀏覽的5條記錄。
思考:如何將瀏覽記錄保存在Cookie中?
回答:只須要保存商品的ID便可,由於每一個商品的ID是惟一的。
實現:把每次瀏覽的商品ID保存一個字符串中,將這個字符串保存在Cookie中,ID和ID之間用分隔符分隔,每次取出前5條記錄。
顯示全部商品的主頁index.jsp
1 <%@page import="entity.Items"%> 2 <%@page import="dao.ItemsDAO"%> 3 <%@ page language="java" import="java.util.*" 4 contentType="text/html; charset=utf-8"%> 5 <!-- 顯示全部的商品信息 --> 6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 7 <html> 8 <head> 9 <title>歡迎光臨網上商城</title> 10 <style type="text/css"> 11 div { 12 float: left; 13 margin: 10px; 14 } 15 16 div dd { 17 margin: 0px; 18 font-size: 10pt; 19 } 20 21 div dd.dd_name { 22 color: blue; 23 } 24 25 div dd.dd_city { 26 color: #000; 27 } 28 </style> 29 </head> 30 31 <body> 32 <h1>商品展現</h1> 33 <hr> 34 <center> 35 <table width="750" height="60" cellpadding="0" cellspacing="0" 36 border="0"> 37 <tr> 38 <td> 39 <!-- 商品循環開始 --> 40 <% 41 ItemsDAO itemsDAO = new ItemsDAO(); 42 ArrayList<Items>list = itemsDAO.getAllItems(); 43 if(list!=null&&list.size()>0){ 44 //遍歷全部的商品 45 for(Items item:list){ 46 %> 47 <div> 48 <dl> 49 <dt> 50 <a href="details.jsp?id=<%=item.getId() %>"> 51 <img src="images/<%=item.getPicture() %>" width="120" height="90" border="1"/> 52 </a> 53 </dt> 54 <dd class="dd_name"><%=item.getName() %></dd> 55 <dd class="dd_city">產地:<%=item.getCity() %> 價格:¥<%=item.getPrice() %></dd> 56 </dl> 57 </div> 58 <% 59 } 60 } 61 %> 62 <!-- 商品循環結束 --> 63 </td> 64 </tr> 65 </table> 66 </center> 67 </body> 68 </html>
顯示商品詳細信息的details.jsp
1 <%@page import="entity.Items"%> 2 <%@page import="dao.ItemsDAO"%> 3 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 4 <!-- 顯示商品詳情,並在右側顯示商品的瀏覽記錄(最近5條記錄) --> 5 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 6 <html> 7 <head> 8 <title>歡迎光臨網上商城</title> 9 <style type="text/css"> 10 div{ 11 float:left; 12 margin-left: 30px; 13 margin-right:30px; 14 margin-top: 5px; 15 margin-bottom: 5px; 16 } 17 div dd{ 18 margin:0px; 19 font-size:10pt; 20 } 21 div dd.dd_name 22 { 23 color:blue; 24 } 25 div dd.dd_city 26 { 27 color:#000; 28 } 29 </style> 30 </head> 31 32 <body> 33 <h1>商品詳情</h1><hr> 34 <center> 35 <table width="750" height="60" cellpadding="0" cellspacing="0" border="0"> 36 <tr> 37 <!-- 商品詳細信息 --> 38 <% 39 Items item = new ItemsDAO().getItemsById(Integer.parseInt(request.getParameter("id"))); 40 if(item!=null){ 41 %> 42 <td width="70%" valign="top"> 43 <table> 44 <tr> 45 <td rowspan="4"><img src="images/<%=item.getPicture()%>" width="200" height="160"/></td> 46 </tr> 47 <tr> 48 <td><b><%=item.getName() %></b></td> 49 </tr> 50 <tr> 51 <td>產地:<%=item.getCity() %></td> 52 </tr> 53 <tr> 54 <td>價格:¥<font color="red"><b><%=item.getPrice() %></b></font></td> 55 </tr> 56 </table> 57 </td> 58 <% 59 } 60 %> 61 <!-- 取得Cookie --> 62 <% 63 String list = ""; 64 // 從客戶端得到Cookie集合 65 Cookie[]cookies = request.getCookies(); 66 if(cookies!=null&&cookies.length>0){ 67 for(Cookie c:cookies){ 68 if(c.getName().equals("ListViewCookie")){ 69 list = c.getValue(); 70 } 71 72 String[] arr = list.split(","); 73 // 相同商品只在瀏覽記錄中存放一次 74 if(Arrays.binarySearch(arr, request.getParameter("id"))<0){ 75 list += request.getParameter("id") + ","; 76 } 77 // 若是瀏覽記錄超過1000條,則清空Cookie 78 if(arr!=null&&arr.length>1000){ 79 list = "";// 清零-置空串 80 } 81 Cookie cookie = new Cookie("ListViewCookie",list); 82 response.addCookie(cookie); 83 } 84 } 85 %> 86 87 <!-- 瀏覽過的商品 --> 88 <td width="30%" bgcolor="#EEE" align="center"> 89 <br /><b>您瀏覽過的商品</b><br /> 90 <!-- 循環開始 --> 91 <% 92 ArrayList<Items>itemsList = new ItemsDAO().getViewList(list); 93 if(itemsList!=null&&itemsList.size()>0){ 94 for(Items i:itemsList){ 95 %> 96 <div> 97 <dl> 98 <dt><img src="images/<%=i.getPicture() %>" width="120" height="90" border="1" /></dt> 99 <dd class="dd_name"><%=i.getName() %></dd> 100 <dd class="dd_city">產地:<%=i.getCity() %> 價格:¥<%=i.getPrice() %></dd> 101 </dl> 102 </div> 103 <% 104 } 105 } 106 %> 107 <!-- 循環結束 --> 108 </td> 109 </tr> 110 </table> 111 </center> 112 </body> 113 </html>
主業務邏輯類ItemsDAO
項目展現:(項目地址:https://git.oschina.net/gaopengfei/JSPLogin.git)
解決中文亂碼:
1)在執行獲取請求參數前設置編碼:
request.setCharacterEncoding(「漢字編碼」);
2)轉換字符編碼:
1 //獲取原始的請求參數值 2 String rawName = request.getParameter("name"); 3 //將請求參數值使用ISO-8859-1字符串分解成字節數組 4 byte[] rawBytes = rawName.getBytes("ISO-8859-1"); 5 //將字節數組從新編碼成字符串 6 String name = new String(rawBytes , "gb2312");
3)獲取請求參數同時轉換編碼:
request.getParameter(「name」).getBytes ("ISO-8859-1");