JSP複習筆記——第11章 JSP 構架和MVC設計模式

11.1 JSP Model I 體系結構  
11.2 JSP Model II 體系結構/MVC設計模式
11.3 使用MVC設計模式改寫用戶註冊程序
    11.3.1 使用serlvet實現Controller層
    11.3.2 使用jsp實現表示層
    11.3.3 使用JavaBean實現模型層
11.3.4 使用JDBC和DAO模式實現數據庫層
   11.4 本章小結


JSP + DAO設計模式

使用JSP+JavaBean開發速度快,有一個問題:JSP與JavaBean之間緊密耦合在一塊兒,會對開發及維護形成麻煩。
使用JSP+JavaBean(模式1)開發適用於一次開發完成,並且團隊成員較少是使用。
JSP + Servlet + JavaBean
對於模式一JSP與JavaBean之間緊密耦合在一塊兒

分析:
JSP優勢,開發前臺界面方便,作UI開發容易
Servlet優勢:是JAVA程序,安全性高,性能高
Servlet缺點:顯示不方便

JavaBean優勢:可重複調用,須要接受用戶的請求參數,進行相應的處理

問題:
JSP跳轉到Servlet能夠經過表單或超連接
從Servlet跳轉到JSP:使用response對象
html

<h1>MVCDEMO</h1>
<!--
<h1><%=request.getAttribute("name")%></h1>
-->
<h1><%=session.getAttribute("name")%></h1>
―――――――――


package org.sky.darkness.servlet ;

import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;

public class MVCServlet extends HttpServlet
{
	public void doGet(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
	{
		this.doPost(req,resp) ;
	}
	public void doPost(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
	{
		// 要傳遞一個值到mvcdemo.jsp中
    // 要傳遞的內容只使用一次
    // 一個頁面跳轉有用,request範圍
    // 既然request沒法傳遞,那就擴大範圍-session
		// req.setAttribute("name","darkness") ;
req.getSession().setAttribute("name","darkness") ;
		resp.sendRedirect("mvcdemo.jsp");
	}
};


JSP中兩種跳轉語句:
四種屬性範圍:
如今從Servlet中要傳遞的值只使用一次,若是把此值存放在session範圍之中,則此內容只要用戶一直與服務器保持鏈接,則此塊內存空間要一直被佔用,那麼性能會很低。

解決方法:RequestDispatcher接口,是用於由Servlet到JSP進行服務器端跳轉的接口
java

req.setAttribute("name","darkness") ;
// 與<jsp:forward/>功能相同
req.getRequestDispatcher("mvcdemo.jsp").forward(req,resp);


-----------------mvc_login.jsp--------------------------------------
<form action="mvcdemo" method="POST">
輸入姓名:<input type="text" name="uname">
<input type="submit" value="提交">
</form>


-----------------MVCServlet.java--------------------------------------
package org.sky.darkness.servlet ;

import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;
import org.sky.darkness.bean.MVCCheck ;

public class MVCServlet extends HttpServlet
{
	public void doGet(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
	{
		this.doPost(req,resp) ;
	}
	public void doPost(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
	{
		String name = req.getParameter("uname") ;
		MVCCheck mc = new MVCCheck() ;
		// 將請求內容設置到mc對象之中
		mc.setName(name) ;
		String path = null ;
		if(mc.isValidate())
		{
			// 保存名字在request範圍之中
			req.setAttribute("name",mc.getName()) ;
			path = "mvc_success.jsp" ;
		}
		else
		{
			path = "mvc_failure.jsp" ;
		}
		// 進行跳轉
		req.getRequestDispatcher(path).forward(req,resp) ;
	}
};
/*
  <servlet>
	<servlet-name>mvc</servlet-name>
	<servlet-class>org.sky.darkness.servlet.MVCServlet</servlet-class>
  </servlet>
  <servlet-mapping>
	<servlet-name>mvc</servlet-name>
	<url-pattern>/mvcdemo</url-pattern>
  </servlet-mapping>
*/


------------------------------------- MVCCheck.java------------------------
package org.sky.darkness.bean ; 

public class MVCCheck
{
	private String name ;

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

	{
		return this.name ;
	}
	// 驗證
	public boolean isValidate()
	{
		if(this.name==null||"".equals(this.name))
		{
			return false ;
		}
		else
		{
			return true ;
		}
	}
};


<%@page contentType="text/html;charset=gb2312"%>
<h1>輸入成功!!!</h1>
<h2>歡迎:<%=request.getAttribute("name")%>光臨!!!</h2>
<%@page contentType="text/html;charset=gb2312"%>
<h1>輸入失敗!!!</h1>
<h2><a href="mvc_login.htm">從新登錄</a></h2>



經過以上代碼能夠發現:
使用MVC開發程序,代碼稍微複雜
JSP與JavaBean之間沒有什麼特別明顯的直接關係
而Servlet根據JavaBean返回的內容進行跳轉

Servlet中最好只有如下幾種代碼:
 接收參數
 調用JavaBean
 進行跳轉
 有一些簡單的邏輯判斷


案例-使用mvc+DAO完成用戶登錄
sql

DROP TABLE person ;

CREATE TABLE person 
(
	id varchar(20) not null primary key ,
	name varchar(20) not null ,
	password varchar(20) 
) ;

INSERT INTO person (id,name,password) VALUES ('sky','darkness','wind') ;
INSERT INTO person (id,name,password) VALUES ('cloud','hacker','creaker') ;

-- 提交事務
commit ;


-----------------login.jsp--------------------------------------------------------------------
<%@page contentType="text/html;charset=gb2312"%>
<%@page import="java.util.*"%>
<html>
<head>
	<title>登錄</title>
</head>
<body>
<center>
	<h1>登錄範例——MVC實現</h1>
	<hr>
	<br>
	<br>
	<!-- 加入更加詳細的錯誤提示 -->
	<%
		if(request.getAttribute("errors")!=null)
		{
			// 有錯誤,要進行打印輸出
			List all = (List)request.getAttribute("errors") ;
			Iterator iter = all.iterator() ;
			while(iter.hasNext())
			{
	%>
				<li><%=iter.next()%>
	<%
			}
		}
	%>
	
	<form action="LoginServlet" method="post">
	<table>
		<tr>
			<td colspan="2">用戶登錄</td>
		</tr>
		<tr>
			<td>用戶名:</td>
			<td><input type="text" name="id" value="${person.id}"></td>
		</tr>
		<tr>
			<td>密&nbsp;&nbsp;碼:</td>
			<td><input type="password" name="password" value="${person.password}"></td>
		</tr>
		<tr>
			<td colspan="2">
			<input type="submit" value="登錄">
			<input type="reset" value="重置">
			</td>
		</tr>
	</table>
	</form>
</center>
</body>
</html>
-------------------------LoginServlet.java---------------------------------------------
// 創建MVC中的C,完成JSP+Servlet+JavaBean的開發模式

package org.sky.darkness.servlet ;

import java.io.* ;
import java.util.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;
import org.sky.darkness.factory.* ;
import org.sky.darkness.vo.* ;

public class LoginServlet extends HttpServlet
{
	public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException
	{
		this.doPost(request,response) ;
	}
	public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException
	{
		// 聲明一個集合類,用於保存錯誤信息
		List errors = new ArrayList() ;
		// 完成登錄驗證,替換掉login_conf.jsp
		String path = "login.jsp" ;
		// 一、接收請求內容
		String id = request.getParameter("id") ;
		String password = request.getParameter("password") ;
		// 二、進行數據合法性驗證,包括是否爲空,長度是否知足等
		// 要將接收到的內容設置給PersonVO對象
		PersonVo pv = new PersonVo() ;
		pv.setId(id) ;
		pv.setPassword(password) ;
		pv.setErrors(errors) ;
		// 三、若是合法,則進行數據庫驗證
		if(pv.invalidate())
		{
			// 數據合法,能夠進行數據庫驗證
			if(DAOFactory.getPersonDAOInstance().isLogin(pv))
			{
				// 用戶ID、密碼合法
				// 修改跳轉路徑
				// 保存用戶名到request範圍之中
				// request.setAttribute("name",pv.getName()) ;
				path = "login_success.jsp" ;
			}
			else
			{
				// 用戶ID、密碼非法
				errors.add("錯誤的用戶ID及密碼!") ;
			}
		}
		// 將錯誤信息保存
		request.setAttribute("errors",errors) ;
		request.setAttribute("person",pv) ;
		request.getRequestDispatcher(path).forward(request,response) ;
	}
};
-------------------------login_success.jsp---------------------------
<%@page contentType="text/html;charset=gb2312"%>
<html>
<head>
	<title>登錄</title>
</head>
<body>
<center>
	<h1>登錄範例——MVC實現</h1>
	<hr>
	<br>
	<br>
	<h2>登錄成功</h2>
	<h3>歡迎<font color="red" size="15">
		${person.name}
	</font>光臨!!!</h3>
</center>
</body>
</html>
-----------------------------PersonVo.java---------------------
// 只包含setter和getter方法的類

package org.sky.darkness.vo ;

import java.util.* ;
public class PersonVo
{
	// 表中全部字段
	private String id ;
	private String name ;
	private String password ;
	// 此屬性用於保存所有錯誤信息
	private List errors ;

	public boolean invalidate()
	{
		boolean flag = true ;
		// 驗證ID
		if(this.id==null||"".equals(this.id))
		{
			flag = false ;
			errors.add("ID不能爲空!") ;
		}
		else
		{
			// 進行長度驗證:3~10位
			if(this.id.length()<3||this.id.length()>10)
			{
				flag = false ;
				errors.add("ID的長度應爲3~10位!") ;
			}
		}
		// 驗證密碼
		if(this.password==null||"".equals(this.password))
		{
			flag = false ;
			errors.add("密碼不能爲空!") ;
		}
		else
		{
			// 進行長度驗證:3~10位
			if(this.password.length()<3||this.password.length()>10)
			{
				flag = false ;
				errors.add("密碼的長度應爲3~10位!") ;
			}
		}
		return flag ;
	}

	public void setErrors(List errors)
	{
		this.errors = errors ;
	}
	public List getErrors()
	{
		return this.errors ;
	}

	// 生成getter和setter方法
	public void setId(String id)
	{
		this.id = id ;
	}
	public void setName(String name)
	{
		this.name = name ;
	}
	public void setPassword(String password)
	{
		this.password = password ;
	}
	public String getId()
	{
		return this.id ;
	}
	public String getName()
	{
		return this.name ;
	}
	public String getPassword()
	{
		return this.password ;
	}
};
----------------------------------PersonDAO.java----------------------
// 本接口定義本項目中所操做person表的所有方法

package org.sky.darkness.dao ;

// 使用PersonVo類
import org.sky.darkness.vo.* ;

public interface PersonDAO
{
	// 須要一個登錄驗證的方法
	public boolean isLogin(PersonVo pv) ;
}
---------------------PersonDAOImpl.java---------------------------------
// 具體實現DAO接口的類

package org.sky.darkness.daoimpl ;

// 須要鏈接數據庫
// 須要對VO的內容進行具體的驗證
import java.sql.* ;
import org.sky.darkness.dao.* ;
import org.sky.darkness.dbc.* ;
import org.sky.darkness.vo.* ;

public class PersonDAOImpl implements PersonDAO
{
	public boolean isLogin(PersonVo pv)
	{
		boolean flag = false ;
		// 在此處成具體的數據庫驗證

		// 聲明一個數據庫操做對象
		PreparedStatement pstmt	= null ;
		// 聲明一個結果集對象
		ResultSet rs			= null ;
		// 聲明一個SQL變量,用於保存SQL語句
		String sql				= null ;
		// DataBaseConnection爲具體的數據庫鏈接及關閉操做類
		DataBaseConnection dbc	= null ;
		// 鏈接數據庫
		dbc = new DataBaseConnection() ;

		// 編寫SQL語句
		sql = "SELECT name FROM person WHERE id=? and password=?" ;
		try
		{			
			// 實例化數據庫操做對象
			pstmt = dbc.getConnection().prepareStatement(sql) ;

			// 設置pstmt的內容,是按ID和密碼驗證
			pstmt.setString(1,pv.getId()) ;
			pstmt.setString(2,pv.getPassword()) ;

			// 查詢記錄
			rs = pstmt.executeQuery() ;
			// 判斷是否有記錄
			if(rs.next())
			{
				// 若是有記錄,則執行此段代碼
				// 用戶是合法的,能夠登錄
				flag = true ;
				pv.setName(rs.getString(1)) ;
			}
			// 依次關閉
			rs.close() ;
			pstmt.close() ;
		}
		catch(Exception e)
		{
			System.out.println(e) ;
		}
		finally
		{
			// 最後必定要保證數據庫已被關閉
			dbc.close() ;
		}
		return flag ;
	}
};
-------------------------DAOFactory.java---------------------
// 取得DAO實例的工廠類

package org.sky.darkness.factory ;

import org.sky.darkness.dao.* ;
import org.sky.darkness.daoimpl.* ;

public class DAOFactory
{
	public static PersonDAO getPersonDAOInstance()
	{
		return new PersonDAOImpl() ;
	}
};
---------------------DataBaseConnection.java------------------
// 本類只用於數據庫鏈接及關閉操做
package org.sky.darkness.dbc ;

import java.sql.* ;

public class DataBaseConnection
{
	// 屬性
	// 定義數據庫操做的常量、對象
	// 數據庫驅動程序
	private final String DBDRIVER	= "oracle.jdbc.driver.OracleDriver" ;
	// 數據庫鏈接地址
	private final String DBURL		= "jdbc:oracle:thin:@localhost:1521:sky" ;
	// 數據庫用戶名
	private final String DBUSER		= "scott" ;
	// 數據庫鏈接密碼
	private final String DBPASSWORD	= "tiger" ;
	// 聲明一個數據庫鏈接對象
	private Connection conn			= null ;

	// 在構造方法之中鏈接數據庫
	public DataBaseConnection()
	{
		try
		{
			// 加載驅動程序
			Class.forName(DBDRIVER) ; 
			// 鏈接數據庫
			conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;	
		}
		catch (Exception e)
		{
			System.out.println(e) ;
		}
	}

	// 返回一個數據庫鏈接
	public Connection getConnection()
	{
		/// 返回鏈接對象
		return this.conn ;
	}

	// 關閉數據庫鏈接
	public void close()
	{
		try
		{
			this.conn.close() ;			
		}
		catch (Exception e)
		{
		}
	}
};
相關文章
相關標籤/搜索