【Web】Jsp基礎學習

Apache目錄結構


Web 目錄結構


WEB-INF下包括下列文件


WEB-INF目錄結構

1.      WEB-INF是java的WEB應用的安全目錄。所謂安全目錄就是客戶端無法訪問,只有服務器端可以訪問的目錄。

2.      Web.xml,項目部署文件。

3.      Classes文件夾,用以放置*.class文件

4.      Lib文件夾,用以存放需要的jar包。

 

MyEclipseJavaWeb項目目錄結構


Web項目虛擬路徑

 

http://localhost:8080/MyFirstWebApp/index.jsp  MyFirstWebApp 叫做Web虛擬路徑

 

可以在下面這個地方配置


訪問路徑就變成了http://localhost:8080/HelloWorld/index.jsp

 

修改tomcat默認的端口號

 

在conf/server.xml文件

<Connector port=”8080”

         Protocol=”HTTP/1.1”

         connectionTimeout=”20000”

         redirecPort=”8443”

/>

 

JSP:

JSP全名爲Java Server Pages 其根本是一個簡化的Servlet設計,他實現了在Java當中使用標準HTML標籤。Jsp是一種動態網頁技術標準,也是JavaEE標準。JSP和Servlet一樣,是在服務器端執行的。

 

常見動態網站開發技術對比

JSP

Java平臺,安全性高,適合開發大型的,企業級的Web應用程序。

Asp.net

.Net平臺,簡單易學。但是安全性以及跨平臺性差。

Php

簡單,高效,成本低開發週期短,特別適合中小型企業Web應用開發。(LAMP:Linux+Apache+MySQL+PHP)

 

Jsp基礎語法

 

Page指令 通常位於jsp頁面的頂端,同一個頁面可以有多個page指令。

Include指令  將一個外部文件嵌入到JSP文件中,同時解析這個頁面中的JSP語句。

Taglib指令  使用標籤庫定義新的自定義標籤,在JSP頁面中啓用定製行爲。

 

Page指令語法

<%@ page 屬性1=“屬性值” 屬性2=“屬性值1,屬性值2…” 屬性n=“屬性值n”%>

屬性

描述

默認值

Language

指定JSP頁面使用的腳本語言

Java

Import

通過該屬性來引用腳本語言中使用到的類文件

ContentType

指定JSP頁面所採用的編碼方式

Text/html  ISO-8859-1

 

JSP 註釋

HTML的註釋

<!—html註釋-->  //客戶端可見

JSP註釋

<%--html註釋--%> //客戶端不可見

JSP腳本註釋

//單行註釋    /**/多行註釋

 

JSP腳本

<% Java代碼 %>

 

Jsp聲明

<%! Java代碼%>

<%!

       String s="ISI";  //聲明瞭一個變量

       int add(int x,int y){ //聲明瞭一個方法

                return x+y;

       }

 %>

 

JSP表達式

<% =表達式%>  //注意:表達式不以分號結束

你好,<%=s%>

 <%=add(3,2) %>

 

JSP頁面聲明週期


JspService()方法被調用來處理客戶端的請求。對每一個請求,JSP引擎創建一個新的線程來處理該請求。如果有多個客戶端同時請求該JSP文件,則JSP引擎會創建多個線程。每個客戶端請求對應一個線程。以多線程方式執行可以大大降低對系統的資源需求,提高系統的併發量和響應時間。但要注意多線程的編程帶來的程序的同步問題,由於該servlet始終常駐與內存,所以響應時間非常快。

 

打印九九乘法表

<%!

                   String printCalculate(){

                            String s="";

                            for(int i = 1;i<=9;i++){

                                     for(int j=1;j<=i;j++){

                                              

                                               s+=(i+"*"+j+"="+(j*i)+"&nbsp;");

                                     }

                                     s+="<br/>";

                            }

                            return s;

                   }

                  

                   //使用腳本打印乘法表

                   void printCalculate1(JspWriter out)throws IOException{

                            String s="";

                            for(int i = 1;i<=9;i++){

                                     for(int j=1;j<=i;j++){

                                              

                                               out.println(i+"*"+j+"="+(j*i)+"&nbsp;");

                                     }

                                     out.println("<br/>");

                            }

                   }

         %> 

         <%=printCalculate()%>

         <%--腳本方式調用要加分號 --%>

         <%printCalculate1(out); %>

 

Get

以明文的方式通過URL提交數據,數據在URL中可以看到。提交的數據最多不超過2KB。安全性較低但效率比post方式高。適合提交數據量不大,安全性不高的數據。比如:搜索、查詢等

Post

將用戶提交信息封裝在HTML HEADER中。適合提交數據量大,安全性高的用戶信息。比如:註冊、修改、上傳等。

 

 

JSP內置對象

JSP內置對象是Web容器創建的一組對象,不使用new關鍵字就可以使用的內置對象。

JSP九大內置對象

介紹

Out對象

Out對象是JspWriter類的實例,是向客戶端輸出內容常用的對象。

常用方法:

1.       Void println() 向客戶端打印字符串

2.       Void clear()清除緩衝區的內容,如果在flush之後調用會拋出異常。

3.       Void clearBuffer();清除緩衝區的內容,如果在flush之後調用不會拋出異常。

4.       Void flush() 將緩衝區內容輸出到客戶端。

5.       Int getBufferSize() 返回緩衝區以字節數的大小,如不設緩衝則爲0

6.       Int getRemaining() 返回緩衝區還剩餘多少可用。

7.       Boolean isAutoFlush() 返回緩衝區滿時,是自動清空還是拋出異常。

8.       Void close() 關閉輸出流。

Request對象

客戶端的請求信息被封裝在request對象中,通過它才能瞭解客戶的需求,然後做出響應。他是HttpServletRequest類的實例。Request對象具有請求域,即完成客戶的請求之前,該對象一直有效。

常用方法:

1.       String getParameter(String name) 返回name指定參數的字符。

2.       String[] getParameterValues(String name) 返回包含參數name的所有值得數組。

3.       Void setAttribute(String,Object);存儲此請求中的屬性。

4.       Object getAttribute(String name) 返回指定屬性的屬性值。

5.       String getContentType() 得到請求體的MIME類型。

6.       String getProtocol() 返回請求用的協議類型及版本號。

7.       String getServerName() 返回接受請求的服務器主機名。

8.       int getServerPort()返回服務器接收此請求所用的端口號

9.       String getCharacterEncoding()返回字符編碼方式

10.   Void setCharacterEncoding()設置請求的字符編碼方式。

11.   Int getContentLength() 返回請求體的長度(以字節數)

12.   String getRemoteAddr()返回發送此請求的客戶端IP地址

13.   String getRealPath(String path) 返回一虛擬路徑的真實路徑

14.   String request.getContextPath()返回上下文路徑

Response對象

Response 對象包含了響應客戶請求的有關信息,但在JSP中很少用到。它是HttpServletReponse類的實例。Response對象具有頁面作用域,即訪問一個頁面時,該頁面內的response對象只能對這次的訪問有效,其他頁面的response對象對當前頁面無效。

1.       String getCharacterEncoding() 返回響應用的是何種字符編碼。

2.       Void setContentType(String type) 設置響應的MIME類型。

3.       PrintWriter getWriter() 返回可以向客戶端輸出字符的一個對象(注意比較:PrintWriter與內置out的區別)PrintWriter輸出總是提前於內置out對象。

4.       SendRedirect(java.lang.String location) 重新定向客戶端請求

Session對象

Session 表示客戶端與服務器的一次會話。

Web中的session指的是用戶在瀏覽某個網站時,從進入網站到瀏覽器關閉所經過的這段時間,也就是用戶瀏覽這個網站所花費的時間,session實際上是一個特定的時間概念。

在服務器的內存中保存着不同用戶的session。

1.       Session對象在第一個JSP頁面被裝載時自動創建,完成會話期管理。

2.       從一個客戶打開瀏覽器並連接到服務器開始,到客戶端關閉瀏覽器離開這個服務器結束,被稱爲一個會話。

3.       當一個客戶訪問一個服務器時,可能會在服務器的幾個頁面之間切換,服務器應當通過某種方法指導這是一個客戶,就需要session對象。

4.       Session對象是HttpSession類的實例。

Session對象的方法

1.       Long getCreationTime() 返回session創建時間。

2.       Public String getId(); 返回session創建時JSP引擎爲它設的唯一ID號。

3.       Public Object setAttribute(String name,Object value) 使用指定名稱將對象綁定到此會話。

4.       Public Object getAttribute(String name) 返回此會話中的指定名稱綁定在一起的對象,如果沒有對象綁定在該名稱下,則返回null。

5.       String[] getValueNames() 返回一個包含此session N種可用屬性的數組。

6.       Int getMaxInctiveInterval(); 返回兩次請求間隔多長時間此session被取消。(單位秒)

7.       SetMaxInctiveInterval(); 設置生存時間。

Session的生命週期

創建: 當客戶端第一次訪問某個jsp或者servlet時候,服務器會爲當前會話創建一個SessionId,每次客戶端向服務器發送請求時,都會將此SessionId攜帶過去,服務器會對此SessionID進行校驗。

活動:某次會話當中通過超鏈接打開的新頁面屬於同一次會話。

只要當前會話頁面沒有全部關閉,重新打開新的瀏覽器窗口訪問同一項目資源時屬於同一次會話。除非本次會話的所有頁面都關閉後再重新訪問某個Jsp或者Servlet將會創建新的會話。

銷燬:1.session.invalidate()方法

      2.Session過期(超時)

      3. 服務器重啓

application對象

Application 對象實現了用戶間數據的共享,可存放全部變量。

Application 開始於服務器的啓動,終止於服務器的關閉。

在用戶的前後連接或不同用戶之間的連接中,可以對Application對象的同一屬性進行操作。

在任何地方對Application對象屬性的操作,都將影響到其他用戶對此的訪問。

服務器的啓動和關閉決定了Application對象的生命。

Application對象是ServletContext類的實例

常用方法:

1.       Public void setAttribute(String name,Object value)使用指定名稱將對象綁定到此會話。

2.       Public Object getAttribute(String name) 返回與此會話中的指定名稱綁定在一起的對象,如果沒有對象綁定在該名稱下,則返回null

3.       Enumeration getAttributeNames()返回所有可用屬性名的枚舉

4.       String getServerInfo() 返回JSP(SERVLET)引擎名及版本號

Page內置對象

Page對象就是指向當前jsp頁面本身,有點像類中的this指針,它是java.lang.Object 類的實例。常用方法如下:

1.       Class getClass() 返回此Object的類

2.       Int hashCode() 返回此Object的hash碼

3.       Boolean equals(Object obj) 判斷此Object是否與指定的Object對象相等。

4.       Void copy(Object obj) 把此Object拷貝到指定的Object對象中。

5.       Object clone() 克隆此Object對象

6.       String toString() 把此Object對象轉換成String類的對象

7.       Void notify() 喚醒一個等待的線程

8.       Void nofityAll() 喚醒所有等待的線程

9.       Void wait(int timeout) 使一個線程處於等待直到timeout結束或被喚醒。

10.   Void wait() 使一個線程處於等待直到被喚醒

PageContext對象

PageContext 對象提供了對JSP頁面內所有的對象及名字空間的訪問。

PageContext 對象可以訪問到本頁所在的session,也可以取本頁所在的Application的某一屬性值。

PageContext對象相當於頁面中所有功能的集大成者。

PageContext 對象的本類名也叫pageContext.

常用方法:

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,int scope) 設置屬性及屬性值。

7.       Object getAttribute(String name,int scope) 在指定範圍內取屬性的值。

8.       Int getAttributeScope(String name) 返回某屬性的作用範圍。

9.       Void forward(String relativeUrlPath) 使當前頁面重導到另一頁面

10.   Void include(String relativeUrlPath) 在當前位置包含另一文件

 

Config對象

Config對象是在一個Servlet初始化時,JSP引擎向它傳遞信息用的,此信息包括Servlet初始化時所要用到的參數(通過屬性名和屬性值構成)以及服務器的有關信息(通過傳遞一個ServletContext對象),常用方法:

1.       ServletContext getServletContext() 返回含有服務器相關信息的ServletContext對象。

2.       String getInitParameter(String name) 返回初始化參數的值。

3.       Enumeration getInitParameterNames() 返回Servlet初始化所需所有參數的枚舉。

Exception 對象

Exception對象是一個異常對象,當一個頁面在運行過程中發生了異常,就產生這個對象。如果一個JSP頁面要應用此對象,就必須把isErrorPage設爲true,否則無法編譯。他實際上是java.lang.Throwable的對象,常用方法如下:

1.       String getMessage() 返回描述異常的信息

2.       String toString() 返回關於異常的簡短描述消息

3.       Void printStackTrace() 顯示異常及其棧軌跡

4.       Throwable FillInStackTrace() 重寫異常的執行棧軌跡

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" errorPage="exception.jsp"%>

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" isErrorPage="true"%>

 

使用URL傳參中文亂碼問題

修改tomcat配置文件server.xml

<Connector port=”8080”protocol=”HTTP/1.1”

         connectionTimeout=”20000”

         redirectPort=”8443”

         URIEncoding=”utf-8”>

重啓tomcat服務器

 

請求轉發與請求重定向

 

請求重定向:客戶端行爲,response.sendRedirect(),從本質上講等同於兩次請求,前一次的請求對象不會保存,傳遞的參數丟失,地址欄的URL地址會改變。

 

請求轉發:服務器行爲,reqeust.getRequestDispatcher().forward(req,resp);是一次請求,轉發後請求對象會保存,地址欄的URL地址不會改變。

 

Session超時時間

 

Tomcat默認session超時時間爲30分鐘。

設置session超時有兩種方式。

1.      session.setMaxInactiveInterval();//單位是秒

2.      在web.xml中配置

<session-config>

           <session-timeout>

                    10

           </session-timeout>

</session-config> //單位是分鐘

 

Javabean

 

Javabeans 就是符合某種特定的規範的Java類。使用Javabeans的好處是解決代碼重複編寫,減少代碼冗餘,功能區分明確,提高代碼的維護性。

 

Javabean設計原則


Public class Students{
	Private String name;
	Private int age;
	Public Students(){}
	Public void setName(String name){this.name=name;}
	Public String getName()(return this.name;)
	Public void setAge(int age){this.age=age;}
	Public int getAge(){return this.age;}
}<strong>
</strong>

Jsp動作

 

JSP動作元素(action elements),動作元素爲請求處理階段提供信息。動作元素遵循XML元素的語法,有一個包含元素名的開始標籤,可以有屬性、可選的內容、與開始標籤匹配的結束標籤。

Jsp動作元素包括五類

 

第一類是與存取Javabean 有關的,包括:

<jsp:userBean><jsp:setProperty><jsp:getProperty>

第二類是JSP1.2就開始有的基本元素,包括6個動作元素

<jsp:include> <jsp:forward><jsp:param> <jsp:plugin> <jsp:params> <jsp:fallback>

第三類是JSP2.0新增加的元素,主要與JSP Document相關,包括六個元素

<jsp:root>  <jsp:declaration> <jsp:scriptlet><jsp:expression> <jsp:text> <jsp:output>

第四類是JSP2.0新增的動作元素,主要是用來動態生成XML元素標籤的值,包括3個動作

<jsp:attribute> <jsp:body><jsp:element>

第五類是JSP2.0新增的動作元素,主要是用在Tag File中,有2個元素

<jsp:invoke> <jsp:dobody>

 

在JSP頁面中使用Javabeans

創建一個JavaBeans類

package com.po;

/**

 * 用戶類

*/

public class Users {

         private String username;

         private String password;

         public String getUsername() {

                   return username;

         }

         public void setUsername(String username) {

                   this.username = username;

         }

         public String getPassword() {

                   return password;

         }

         public void setPassword(String password) {

                   this.password = password;

         }

         public Users(){}

}

 

1.  像使用普通java類一樣,創建javabean實例。

<%@ page import="com.po.Users" %>

<%

                Users user = new Users();

                user.setPassword("123");

                user.setUsername("lisi");

   %>

<h1>使用普通方式創建javaBean實例</h1>

     用戶名:<%=user.getUsername() %><br/>

     密碼:<%=user.getPassword() %>

1.      在Jsp頁面中通常使用jsp動作標籤使用javabean

UserBeans動作

setProperty動作

getProperty動作

<jsp:useBean>

作用:在jsp頁面中實例化或者在指定範圍內使用javabean

<jsp:useBean id=”標識符” class=”java類名” scope=”作用範圍”/>

例:

<jsp:useBean id="myUsers" class="com.po.Users" scope="page"></jsp:useBean>

     <h1>使用useBean創建javaBean實例</h1>

     用戶名:<%=myUsers.getUsername() %><br/>

     密碼:<%=myUsers.getPassword() %>

這裏獲取的值都爲null

<jsp:setProperty>

作用:給已經實例化的Javabean對象的屬性賦值,一共有四種形式

1.       <jsp:setProperty name=”javaBean實例名” property=”*”/> (跟表單關聯)

<jsp:useBean id="myUsers" class="com.po.Users" scope="page"></jsp:useBean>

    <h1>setProperty用法</h1><hr>

    <!-- 根據表單名字和Javabean名字自動匹配所有的屬性 -->

    <jsp:setProperty property="*" name="myUsers"/>

用戶名:<%=myUsers.getUsername() %><br/>

       密碼:<%=myUsers.getPassword() %>

2.       <jsp:setProperty name=”javaBean實例名” property=”JavaBean屬性名”/> (跟表單關聯)

對部分屬性進行匹配,這裏只匹配用戶名,密碼顯示爲空

<jsp:useBean id="myUsers" class="com.po.Users" scope="page"></jsp:useBean>

    <h1>setProperty用法</h1><hr>

    <jsp:setProperty property="username" name="myUsers"/>

用戶名:<%=myUsers.getUsername() %><br/>

       密碼:<%=myUsers.getPassword() %>

3.       <jsp:setProperty name=”JavaBean實例名” property=”JavaBean屬性名” value=”BeanValue”/>(手工設置)

和表單無關,通過手工賦值的方法。

<jsp:setProperty property="username" name="myUsers" value="lisi"/>

    <jsp:setProperty property="password" name="myUsers" value="123"/>

用戶名:<%=myUsers.getUsername() %><br/>

       密碼:<%=myUsers.getPassword() %>

4.       <jsp:setProperty name=”JavaBean實例名” property=”propertyName” param=”request對象中的參數名”/>(跟request參數關聯)

Param 可以是url地址傳參的方式給javabean賦值,密碼顯示666

<form action="setProperty.jsp?mypass=666" method="post">

<jsp:setProperty property="password" name="myUsers" param="mypass"/>

用戶名:<%=myUsers.getUsername() %><br/>

       密碼:<%=myUsers.getPassword() %>

<jsp:getProperty>

作用: 獲取指定Javabean對象的屬性值

<jsp:getProperty name=”JavaBean實例名” property=”屬性名”/>

用戶名:<jsp:getProperty property="username" name="myUsers"/><br/>

密碼:<jsp:getProperty property="password" name="myUsers"/>

    <%--用戶名:<%=myUsers.getUsername() %><br/>

     密碼:<%=myUsers.getPassword() %> --%>

 

Javabean的四個作用域範圍

說明:使用useBeans的scope屬性可以用來指定javabean的作用範圍

Page

僅在當前頁面有效

Request

可以通過HttpRequest.getAttribute()方法獲取JavaBean對象

Session

可以通過HttpSession.getAttribute()方法獲取JavaBean對象

Application

可以通過application.getAttribute()方法取得JavaBean對象

<jsp:useBean id="myUsers" class="com.po.Users" scope="application"></jsp:useBean>

用戶名:<jsp:getProperty property="username" name="myUsers"/><br/>

密碼:<jsp:getProperty property="password" name="myUsers"/><hr>

   <!-- 通過內置對象方式獲取 -->

用戶名<%=((Users)application.getAttribute("myUsers")).getUsername()%><br/>

密碼:<%=((Users)application.getAttribute("myUsers")).getPassword()%>

 

Model1簡介

 

在Model 1 出現之前,整個Web應用的情況:幾乎全部由JSP頁面組成,JSP頁面接收處理客戶端的請求,對請求處理後直接作出響應。

 

Javabean的出現可以使jsp頁面中使用Javabean封裝的數據或者調用 Javabean的業務邏輯代碼,這樣大大提升了程序的可維護性。



例子:Model 1登錄案例

Login.jsp  登錄界面

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    <form action="dologin.jsp" method="post">
    	用戶名:<input type="text" name="username"/><br/>
    	密碼:<input type="password" name="password" value=""/><br/>
    	<input type="submit" value="登錄"> 
    </form>
  </body>
</html>
Users.java  Javabean 

package com.po;
public class Users {
	private String username;
	private String password;
	public Users(){
		
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}
UsersDAO.java  處理數據操作

package com.dao;
import com.po.Users;
//用戶的業務邏輯
public class UsersDAO {
	//用戶登錄方法
	public boolean usersLogin(Users u){
		if("admin".equals(u.getUsername())&&"admin".equals(u.getPassword())){
			return true;
		}else{
			return false;
		}
	}
}
dologin.jsp  處理登錄,登錄成功或失敗分別跳轉到不同頁面

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<jsp:useBean id="loginUser" class="com.po.Users" scope="page"></jsp:useBean>
<jsp:useBean id="userDao" class="com.dao.UsersDAO" scope="page"></jsp:useBean>
<jsp:setProperty property="*" name="loginUser"/>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

if(userDao.usersLogin(loginUser)){

	session.setAttribute("loginUser",loginUser.getUsername() );
	request.getRequestDispatcher("login_success.jsp").forward(request, response);
}else{
	response.sendRedirect("login_fail.jsp");
}
%>

Jsp狀態管理

 

http協議的無狀態性

 

無狀態是指,當瀏覽器發送請求給服務器的時候,服務器響應客戶端的請求。

但是當同一個瀏覽器再次發送請求給服務器的時候,服務器並不知道它就是剛纔那個瀏覽器。

簡單地說,就是服務器不會記得你,所以就是無狀態協議。

 

Cookie

Cookie: 是Web服務器保存在客戶端的一系列文本信息。

典型應用一:判斷註冊用戶是否已經登錄網站。

典型應用二:“購物車”的處理。

Cookie的作用:

         對特定對象的追蹤。

         保存用戶網頁瀏覽記錄與習慣。

         簡化登錄。

安全風險:容易泄露用戶的信息。

 

Jsp中創建與使用Cookie

創建Cookie對象

Cookie newCookie = new Cookie(String key ,Object value);

寫入Cookie對象

Response.addCookie(new Cookie);

讀取Cookie對象

Cookie[] cookies= request.getCookies();

Cookie的常用方法

Void setMaxAge(int expiry)

設置cookie的有效期,以秒爲單位

Void setValue(String value)

在cookie創建後,對cookie進行賦值

String getName()

獲取cookie的名稱

String getValue()

獲取cookie的值

Int getMaxAge()

獲取cookie的有效時間,以秒爲單位

 

案例:記住用戶的用戶名和密碼的登錄狀態。

login.jsp

<%@ page language="java" import="java.util.*,java.net.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
  <%
    	String username="";
    	String password="";
    	Cookie[] cookies = request.getCookies();
    	if(cookies != null && cookies.length>0){
    		for(Cookie c: cookies){
    			if(c.getName().equals("username")){
    				username = URLDecoder.decode(c.getValue(),"utf-8");
    			}
    			if(c.getName().equals("password")){
    				password = c.getValue();
    			}
    		}
    	}
    	
     %>
    <form action="dologin.jsp" method="post">
    	用戶名:<input type="text" name="username" value="<%=username%>"/><br/>
    	密碼:<input type="password" name="password" value="<%=password %>"/><br/>
    	記住我的登錄狀態<input type="checkbox" name="isUseCookie" checked="checked"/><br/>
    	<input type="submit" value="登錄"> <input type="reset" value="取消">
    </form>
  </body>
</html>
dologin.jsp 處理登錄邏輯,向客戶端寫Cookie

<%@page import="java.net.CookieStore"%>
<%@ page language="java" import="java.util.*,java.net.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'users.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  <!-- 
  	Cookie 中文亂碼,需要使用 java.net.* 包裏的類來處理
   -->
  
  <body>
    <h1>用戶登錄</h1>
    <%
    	request.setCharacterEncoding("utf-8");
    	//判斷用戶是否點擊了記住登錄狀態
    	String[] isUserCookies = request.getParameterValues("isUseCookie");
    	if(isUserCookies != null && isUserCookies.length >0){
    		//把用戶名和密碼保存在Cookie對象裏面
    		//使用URLEncoder 解決無法再Cookie中存儲中文問題
    		String username= URLEncoder.encode(request.getParameter("username"),"utf-8");
    		String password=request.getParameter("password");
    		
    		Cookie usernameCookie = new Cookie("username",username);
    		Cookie passwordCookie = new Cookie("password",password);
    		//設置最大生存期限
    		usernameCookie.setMaxAge(864000);
    		passwordCookie.setMaxAge(864000);
    		response.addCookie(usernameCookie);
    		response.addCookie(passwordCookie);
    	}else{
    		//把已經保存的cookie 清空
    		Cookie[] cookies = request.getCookies();
    		if(cookies != null && cookies.length>0){
    			for(Cookie c : cookies){
    				if(c.getName().equals("username") || c.getName().equals("password")){
    					c.setMaxAge(0);//設置最大時間爲0,使其失效
    					response.addCookie(c);
    				}
    			
    			}
    		}
    	}
     %>
    
    <a href="users.jsp" target="_blank">查看用戶名和密碼</a>
    <hr>
  </body>
</html>
users.jsp 讀取cookie中用戶的登錄信息

<%@ page language="java" import="java.util.*,java.net.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">  
    <title>My JSP 'users.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>  
  <body>
    <h1>查看用戶信息</h1>  
    <%
    	String username="";
    	String password="";
    	Cookie[] cookies = request.getCookies();
    	if(cookies != null && cookies.length>0){
    		for(Cookie c: cookies){
    			if(c.getName().equals("username")){
    				username = URLDecoder.decode(c.getValue(),"utf-8");
    			}
    			if(c.getName().equals("password")){
    				password = c.getValue();
    			}
    		}
    	}  	
     %>
    <hr>
    用戶名:<%=username %><br/>
 密碼:<%=password %>
  </body>
</html>

Session與Cookie對比

Session

Cookie

在服務器端保存用戶信息

Session中保存的是Object類型

隨會話的結束而將其存儲的數據銷燬

保存重要的信息

在客戶端保存用戶信息

Cookie保存的是String類型

Cookie可以長期保存在客戶端

保存不重要的用戶信息

 

Include指令

語法:

<%@ include file=”URL”%>

 

Include動作

語法:

<jsp:include page=”URL”flush=”true|false”/>

Page 表示要包含的頁面

Flush 表示是否從緩衝區中讀取頁面

 

Include指令與include動作比較

 

Include指令

Jsp:include 動作

語法格式

<%@ include file=” ..”%>

<jsp:include page=”..”>

發生作用的時間

頁面編譯期間

請求期間

包含的內容

文件的實際內容

頁面的輸出

轉換成Servlet

主頁面和包含頁面轉換爲一個Servlet

主頁面和包含頁面轉換爲獨立的Servlet

編譯時間

較慢—資源必須被解析

較快

執行時間

稍快

較慢—每次資源必須被解析

 

Forward動作

語法:

<jsp:forward page=”URL”/>

 

等同於服務器轉發:

Request.getRequestDispatcher(“/url”).forward(request,response);

 

Param動作

語法:

<jsp:param name=”參數名” value=”參數值”>

常常與 <jsp:forward> 一起使用,作爲其子標籤。

<jsp:forward page=”xxx.jsp”>

   <jsp:param name=”email” value=”[email protected]”>

</jsp:forward>

 

小案例:商品瀏覽記錄



1.首先,打開mysql數據庫,創建表和插入數據

DROP TABLE IF EXISTS `items`;
CREATE TABLE `items` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) default NULL,
  `city` varchar(50) default NULL,
  `price` int(11) default NULL,
  `number` int(11) default NULL,
  `picture` varchar(500) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

-- ----------------------------

-- ----------------------------
INSERT INTO `items` VALUES ('1', '沃特籃球鞋', '佛山', '180', '500', '001.jpg');
INSERT INTO `items` VALUES ('2', '安踏運動鞋', '福州', '120', '800', '002.jpg');
INSERT INTO `items` VALUES ('3', '耐克運動鞋', '廣州', '500', '1000', '003.jpg');
INSERT INTO `items` VALUES ('4', '阿迪達斯T血衫', '上海', '388', '600', '004.jpg');
INSERT INTO `items` VALUES ('5', '李寧文化衫', '廣州', '180', '900', '005.jpg');
INSERT INTO `items` VALUES ('6', '小米3', '北京', '1999', '3000', '006.jpg');
INSERT INTO `items` VALUES ('7', '小米2S', '北京', '1299', '1000', '007.jpg');
INSERT INTO `items` VALUES ('8', 'thinkpad筆記本', '北京', '6999', '500', '008.jpg');
INSERT INTO `items` VALUES ('9', 'dell筆記本', '北京', '3999', '500', '009.jpg');
INSERT INTO `items` VALUES ('10', 'ipad5', '北京', '5999', '500', '010.jpg');
2. 創建數據庫幫助類,獲取數據庫連接對象 DBHelper.java

package util;
import java.sql.Connection;
import java.sql.DriverManager;
public class DBHelper {
	private static final String driver ="com.mysql.jdbc.Driver";//加載數據庫驅動
	//連接數據庫的URL地址
	private static final String url = "jdbc:mysql://localhost:3306/shopping?useUnicode=true&characterEncoding=UTF-8";
	private static final String username="root";//數據庫用戶名
	private static final String password="limeng";//數據庫密碼
	
	private static Connection conn= null;
	static{
		
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	//單例模式返回數據庫連接對象
	public static Connection getConnection() throws Exception{
		if(conn== null){
			conn = DriverManager.getConnection(url,username,password);
			return conn;
		}
		return conn;
	}
}
3.創建實體類Items.java 和數據庫的字段對應

package entity;
//商品類
public class Items {
	private int id;
	private String name;//名字
	private String city;//產地
	private int price;//價格
	private int number;//庫存
	private String picture;//圖片
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	public String getPicture() {
		return picture;
	}

	public void setPicture(String picture) {
		this.picture = picture;
	}
}
4.創建業務邏輯類 ItemsDAO.java 處理不同的業務邏輯

package dao;

import java.awt.event.ItemListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import util.DBHelper;
import entity.Items;

//商品業務邏輯類
public class ItemsDAO {
	
	//獲取所有的商品信息
	public ArrayList<Items> getAllItems(){
		Connection conn = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		ArrayList<Items> list = new ArrayList<Items>();
		try {
			conn = DBHelper.getConnection();
			String sql = "select * from items;";
			stmt = conn.prepareStatement(sql);
			rs = stmt.executeQuery();
			while(rs.next()){
				Items item = new Items();
				item.setId(rs.getInt("id"));
				item.setName(rs.getString("name"));
				item.setCity(rs.getString("city"));
				item.setNumber(rs.getInt("number"));
				item.setPrice(rs.getInt("price"));
				item.setPicture(rs.getString("picture"));
				list.add(item);
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			
			try {
				if(rs != null){
					rs.close();
				}
				if(stmt != null){
					stmt.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return list;
	}
	
	//根據商品編號獲取商品資料
	public Items getItemById(int id){
		Connection conn = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			conn = DBHelper.getConnection();
			String sql = "select * from items where id=?;";
			stmt = conn.prepareStatement(sql);
			stmt.setInt(1, id);
			rs = stmt.executeQuery();
			if(rs.next()){
				Items item = new Items();
				item.setId(rs.getInt("id"));
				item.setName(rs.getString("name"));
				item.setCity(rs.getString("city"));
				item.setNumber(rs.getInt("number"));
				item.setPrice(rs.getInt("price"));
				item.setPicture(rs.getString("picture"));
				return item;
			}else{
				
				return null;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}finally{
			try {
				if(rs != null){
					rs.close();
				}
				if(stmt != null){
					stmt.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	//獲取最近瀏覽信息
	public ArrayList<Items> getViewList(String list){
		String[] ids = list.split("#");
		ids = array_unique(ids);//去除重複的id
		ArrayList<Items> itemsList = new ArrayList<Items>();
		if(ids != null && ids.length>0){
			if(ids.length>=5){
				for(int i = 0;i<5;i++){
					Items items = getItemById(Integer.parseInt(ids[i]));
					itemsList.add(items);
				}
				return itemsList;
			}else{
				for(int i= 0;i<ids.length;i++){
					Items items = getItemById(Integer.parseInt(ids[i]));
					itemsList.add(items);
				}
				return itemsList;
			}
		}
		return null;
	}
	
	//去除數組中重複的記錄  
	public static String[] array_unique(String[] a) {  
	    // array_unique  
	    List<String> list = new LinkedList<String>();  
	    for(int i = a.length-1; i >=0; i--) {  
	        if(!list.contains(a[i])) {  
	            list.add(a[i]);  
	        }
	    }  
	    return (String[])list.toArray(new String[list.size()]);
	}  
}
5. index.jsp 顯示所有商品列表

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%@ page import="dao.ItemsDAO,entity.Items" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<style type="text/css">
	   div{
	      float:left;
	      margin: 10px;
	   }
	   div dd{
	      margin:0px;
	      font-size:10pt;
	   }
	   div dd.dd_name
	   {
	      color:blue;
	   }
	   div dd.dd_city
	   {
	      color:#000;
	   }
	</style>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
   <h1>商品展示</h1>
   <hr>
   	<center>
   		<table width="770" height="60" cellpadding="0" cellspacing="0" border="0"> 
   			<tr>
   			<td>
   				<!-- 商品循環開始 -->
   				<%
   					ItemsDAO itemsDAO = new ItemsDAO();
   					ArrayList<Items> list = itemsDAO.getAllItems();
   					//開始循環
   					if(list != null && list.size()>0){
   					for(int i= 0;i<list.size();i++){
   					Items item = list.get(i);
   				 %>
   				 <div>
   				 	<dl>
   				 		<dt>
   				 			<a href="detail.jsp?id=<%=item.getId()%>"><img src="images/<%=item.getPicture()%>" width="120" height="90" border="1"></a>
   				 		</dt>
   				 		<dd class="dd_name"><%=item.getName() %></dd>
   				 		<dd class="dd_city">產地<%=item.getCity() %>  價格¥<%=item.getPrice() %></dd>
   				 	</dl>
   				 </div>
   				<!-- 商品循環結束 -->
   				<%
   					}
   				}
   				 %>
   				</td>
   			</tr>
   		</table>
   	
   	</center>
   	
  </body>
</html>
6. detail.jsp 顯示商品詳情和最近瀏覽記錄(最多顯示5條)

<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%@ page import="dao.ItemsDAO,entity.Items" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'detail.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
   		<h1>商品詳情列表</h1><hr>
   	<center>
   	<table width="770" height="60" cellpadding="0" cellspacing="0" border="0"> 
   		<tr>
   			<!-- 商品詳情 -->
   			<%
   				ItemsDAO dao = new ItemsDAO();
   				Items item = dao.getItemById(Integer.parseInt(request.getParameter("id")));
   				if(item != null){
   			%>
   			<td width="70%" valign="top">
   			<table>
               <tr>
                 <td rowspan="4"><img src="images/<%=item.getPicture()%>" width="200" height="160"/></td>
               </tr>
               <tr>
                 <td><B><%=item.getName() %></B></td> 
               </tr>
               <tr>
                 <td>產地:<%=item.getCity()%></td>
               </tr>
               <tr>
                 <td>價格:<%=item.getPrice() %>¥</td>
               </tr> 
             </table>
   			</td>
   	<%
   		}
	%>
   	  <% 
              String list ="";
              //從客戶端獲得Cookies集合
              Cookie[] cookies = request.getCookies();
              //遍歷這個Cookies集合
              if(cookies!=null&&cookies.length>0)
              {
	              for(Cookie c:cookies)
	              {
	                  if(c.getName().equals("ListViewCookie"))
	                  {
	                     list = c.getValue();
	                  }
	              }
	          }
              
              list+=request.getParameter("id")+"#";
              //如果瀏覽記錄超過1000條,清零.
              String[] arr = list.split("#");
              if(arr!=null&&arr.length>0)
              {
                  if(arr.length>=1000)
                  {
                  	list = "";
                  	//清空後前900條
                  	for(int i =arr.length-101;i<arr.length;i++){
                  		list+= arr[i];
                  	}
                  }
              }
              Cookie cookie = new Cookie("ListViewCookie",list);
              response.addCookie(cookie);
          
          %>
          <!-- 瀏覽過的商品 -->
          <td width="30%" bgcolor="#EEE" align="center">
             <br>
             <b>您瀏覽過的商品</b><br>
             <!-- 循環開始 -->
             <% 
                ArrayList<Items> itemlist = dao.getViewList(list);
                if(itemlist!=null&&itemlist.size()>0 )
                {
                   System.out.println("itemlist.size="+itemlist.size());
                   for(Items i:itemlist)
                   {
                         
             %>
             <div>
             <dl>
               <dt>
                 <a href="details.jsp?id=<%=i.getId()%>"><img src="images/<%=i.getPicture() %>" width="120" height="90" border="1"/></a>
               </dt>
               <dd class="dd_name"><%=i.getName() %></dd> 
               <dd class="dd_city">產地:<%=i.getCity() %>  價格:<%=i.getPrice() %> ¥ </dd> 
             </dl>
             </div>
             <% 
                   }
                }
             %>
             <!-- 循環結束 -->
          </td>
   		</tr>
   	</table>
   	</center>	
   
   	 
  </body>
</html>


知識點來自慕課網 點擊打開鏈接














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章