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对象

MVCDEMO



<%=session.getAttribute("name")%>


―――――――――


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进行服务器端跳转的接口

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


-----------------mvc_login.jsp--------------------------------------

输入姓名:




-----------------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) ;
}
};
/*

mvc
org.sky.darkness.servlet.MVCServlet


mvc
/mvcdemo

*/


------------------------------------- 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"%>

输入成功!!!


欢迎:<%=request.getAttribute("name")%>光临!!!


<%@page contentType="text/html;charset=gb2312"%>

输入失败!!!


重新登陆





通过以上代码可以发现:
使用MVC开发程序,代码稍微复杂
JSP与JavaBean之间没有什么特别明显的直接关系
而Servlet根据JavaBean返回的内容进行跳转

Servlet中最好只有以下几种代码:
 接收参数
 调用JavaBean
 进行跳转
 有一些简单的逻辑判断


案例-使用mvc+DAO完成用户登陆

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.*"%>


登陆



登陆范例——MVC实现









<%
if(request.getAttribute("errors")!=null)
{
// 有错误,要进行打印输出
List all = (List)request.getAttribute("errors") ;
Iterator iter = all.iterator() ;
while(iter.hasNext())
{
%>
  • <%=iter.next()%>
    <%
    }
    }
    %>

















    用户登陆
    用户名:
    密  码:








  • -------------------------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" ;
    // 1、接收请求内容
    String id = request.getParameter("id") ;
    String password = request.getParameter("password") ;
    // 2、进行数据合法性验证,包括是否为空,长度是否满足等
    // 要将接收到的内容设置给PersonVO对象
    PersonVo pv = new PersonVo() ;
    pv.setId(id) ;
    pv.setPassword(password) ;
    pv.setErrors(errors) ;
    // 3、如果合法,则进行数据库验证
    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"%>


    登陆



    登陆范例——MVC实现








    登陆成功


    欢迎
    ${person.name}
    光临!!!





    -----------------------------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)
    {
    }
    }
    };

    你可能感兴趣的:(前后台代码衔接研究)