实例: 用一个用户登录验证实例讲解MVC设计模式

   登录程序之前已经学过,是使用JSP+JDBC完成的开发操作,但是之前的登录程序开发中可以发现有很多的问题,就是一个JSP文件中代码过多了,即便是使用了JSP+javaBean的开发模式,其本身也存在JSP中代码过多的问题。

   现在我们就可以利用MVC设计模式来彻底解决掉这些代码过多的问题了

Web开发模式【实例篇】MVC--迈向标准开发_JSP

    在本程序中,用户输入的登录信息提交给Servlet进行接收,Servlet接收到请求内容后首先对其合法性进行检验(如果输入的内容是否为空或者长度是否满足要求等),如果验证失败,则将错误信息传递给登录页显示;如果数据合法,则调用DAO层完成数据库的验证,根据验证的结构跳转到登录成功或登录失败的页面

 需要开发的页面橄榄如下:

Web开发模式【实例篇】MVC--迈向标准开发_JSP_02

首先建立数据库   (我们用的数据库是MySqL,不会的同学可以到这儿                http://zhaoyuqiang.blog.51cto.com/6328846/1127226)学习

  创建数据库,名字为:  51ctomvctest  

  创建表  ,  名字为:  user

  设计表,如下:(注意红色部分,不要忘记编码,否则可能出现不能输入中文现象

Web开发模式【实例篇】MVC--迈向标准开发_MVC实例_03

   在表中填写信息,如下图所示:

Web开发模式【实例篇】MVC--迈向标准开发_modeII_04

 开发工具部署(我们用的是MyEclipse)

 部署如下图所示:

Web开发模式【实例篇】MVC--迈向标准开发_MVC实例_05      

Web开发模式【实例篇】MVC--迈向标准开发_MVC实例_06 

 导入sql的jar包文件,这个不用我再说了吧。

  代码编写

 按照DAO的设计标准,首先应该定义出VO

  1. User.java 
  2. //vo中的属性与数据库表中的属性对应 
  3. package mvc.vo; 
  4. public class User { 
  5.      private String userid; 
  6.      private String name; 
  7.      private String password; 
  8.      public String getUserid(){ 
  9.          return userid; 
  10.      } 
  11.      public void setUserid(String userid){ 
  12.          this.userid=userid; 
  13.      } 
  14.      public String getPassword(){ 
  15.          return password; 
  16.      } 
  17.      public void setPassword(String password){ 
  18.          this.password=password; 
  19.      } 
  20.      public String getName(){ 
  21.          return name; 
  22.      } 
  23.      public void setName(String name){ 
  24.          this.name=name; 
  25.      } 

 DAO中需要进行数据库的连接操作,需要DatabaseConnection的类负责数据的操作

  1.  DatabaseConnection.java 
  2. //负责数据库的打开与关闭操作 
  3. package mvc.dbc; 
  4. import java.sql.*; 
  5. public class DatabaseConnection { 
  6.     private static final String DBdriver="org.gjt.mm.mysql.Driver"
  7.     private static final String DBURL="jdbc:mysql://localhost:3306/51ctomvctest"
  8.     private static final String DBUSER="root"
  9.     private static final String DBPASS="425680992"
  10.     private Connection conn=null;  
  11.     public DatabaseConnection()throws Exception{   //在构造方法中进行数据库连接 
  12.        try{ 
  13.            Class.forName(DBdriver);//加载驱动程序 
  14.             this.conn=DriverManager.getConnection(DBURL,DBUSER,DBPASS);//连接数据库 
  15.        }catch(Exception e){ 
  16.             throw e; 
  17.        }     
  18.    } 
  19.     public Connection getConnection(){//取得数据库连接 
  20.       return this.conn;//取得数据连接  
  21.     } 
  22.     public void close()throws Exception{//关闭数据库操作 
  23.         if(this.conn!=null){//避免NullPointerException 
  24.             try{ 
  25.                 this.conn.close();//关闭数据库 
  26.             }catch(Exception e){ 
  27.                 throw e; 
  28.             } 
  29.         } 
  30.     } 

  由于本程序的核心功能是完成用户登录验证,所以在定义DAO的时候,定义一个验证方法

  1. IUserDAO.java 
  2. //定义一个登陆验证的方法,这个方法为执行查询操作,并且采用了findXxx()的命名形式 
  3. package mvc.dao; 
  4. import mvc.vo.User; //引用mvc.vo包里面的User类 
  5. public interface IUserDAO { 
  6.         /** 
  7.          * 用户登录验证 
  8.          *@param user 传入VO对象 
  9.          *@param 验证的操作结果 
  10.          *@throw Exception 
  11.          */ 
  12.     public boolean findLogin(User user)throws Exception; 

 下面分别编写实现类和代理类

  1. UserDAOImpl.java 
  2. //定义实现类,在此类中将通过输入用户ID和密码进行验证, 
  3. //如果验证成功,则通过VO将用户的真实姓名取出并返回 
  4. package mvc.dao; 
  5. import java.sql.*; 
  6. import mvc.dao.IUserDAO; 
  7. import mvc.vo.User; 
  8. public class UserDAOImpl implements IUserDAO{ 
  9.     private Connection conn=null;//定义数据库连接对象 
  10.     private PreparedStatement pstmt=null;//定义数据库连接对象 
  11.     public UserDAOImpl(Connection conn){//设置数据库连接 
  12.         this.conn=conn;  
  13.     } 
  14.     public boolean findLogin(User user)throws Exception{ 
  15.         boolean flag=false
  16.         try{ 
  17.             String sql="select name from user where userid=? and password=?"
  18.             thisthis.pstmt=this.conn.prepareStatement(sql);//实例化操作 
  19.             this.pstmt.setString(1,user.getUserid());//设置id 
  20.             this.pstmt.setString(2,user.getPassword());//设置密码 
  21.             ResultSet rs=this.pstmt.executeQuery();//取得查询结果 
  22.             if(rs.next()){ 
  23.                 user.setName(rs.getString(1));//取得姓名 
  24.                 flag=true;//登录成功 
  25.             } 
  26.         }catch(Exception e){ 
  27.             throw e; 
  28.         }finally{ 
  29.             if(this.pstmt!=null){ 
  30.                 try{ 
  31.                     this.pstmt.close();//关闭操作 
  32.                 }catch(Exception e){ 
  33.                     throw e; 
  34.                 } 
  35.             } 
  36.         } 
  37.         return flag; 
  38.     } 
  39.     } 

  1. UserDAOProxy.java 
  2. package mvc.dao; 
  3. import mvc.dao.*; 
  4. import mvc.dbc.*; 
  5. import mvc.vo.*; 
  6. public class UserDAOProxy implements IUserDAO{ 
  7.   private DatabaseConnection dbc=null;//定义数据库连接 
  8.   private IUserDAO dao=null;//定义DAO接口 
  9.   public UserDAOProxy(){ 
  10.       try{ 
  11.          this.dbc=new DatabaseConnection();//实例化数据库连接  
  12.       }catch(Exception e){ 
  13.           e.printStackTrace(); 
  14.       } 
  15.       this.dao=new UserDAOImpl(this.dbc.getConnection()); 
  16.   } 
  17.   public boolean findLogin(User user)throws Exception{ 
  18.       boolean flag=false
  19.       try{ 
  20.           flag=this.dao.findLogin(user);//调用真实主题 
  21.       }catch(Exception e){ 
  22.           throw e; 
  23.        }finally{ 
  24.            this.dbc.close(); 
  25.        } 
  26.        return flag; 
  27.   } 

  定义工厂类 取得DAO实例

  1. DAOFactory.java 
  2. package mvc.factory; 
  3. import mvc.dao.*; 
  4. public class DAOFactory { 
  5.     public static IUserDAO getIUserDAOInstance(){//取得DAO实例 
  6.          return new UserDAOProxy();//返回代理实例  
  7.     } 
  8.     } 

 DAO的操作完成只是数据层的操作,下面需要编写Servlet

  1.  LoginServlet.java 
  2. //定义Servlet,在Servlet中要接受客户端发来的输入数据 
  3. //同时要调用DAO,并且要根据DAO的结果返回响应的信息 
  4. //在Servlet中,首先定义对接受的userid和userpass两个参数进行验证,如果没有输入参数//或者是输入的参数为空,则会在info对象中增加相应的错误信息。 
  5. //当验证通过后,程序将调用DAO进行数据层的验证,并根据DAO的返回结果来决定返回//给客户端的信息 
  6. package mvc.servlet; 
  7. import java.io.*; 
  8. import java.util.*; 
  9. import javax.servlet.*; 
  10. import javax.servlet.http.*; 
  11. import mvc.factory.*; 
  12. import mvc.vo.*; 
  13. public class LoginServlet extends HttpServlet{ 
  14.       public void doGet(HttpServletRequest req,HttpServletResponse resp) 
  15.               throws ServletException,IOException{ 
  16.           String path="login.jsp"
  17.           String userid=req.getParameter("userid");//接受userid内容 
  18.           String userpass=req.getParameter("userpass");//接受password内容 
  19.           List<String>info=new ArrayList<String>();//保存所有返回信息 
  20.           if(userid == null||"".equals(userid)){ 
  21.               info.add("用么id不能为空!"); 
  22.           } 
  23.           if(userpass==null||"".equals(userpass)){ 
  24.               info.add("密码不能为空!"); 
  25.           } 
  26.           if(info.size()==0){//用户名和密码验证通过 
  27.             User user=new User();//实例化VO 
  28.             user.setUserid(userid);//设置userid 
  29.             user.setPassword(userpass);//设置password 
  30.             try{ 
  31.                 if(DAOFactory.getIUserDAOInstance().findLogin(user)){//验证通过 
  32.                     info.add("用户登录成功,欢迎"+user.getName()+"光临!"); 
  33.                 }else{ 
  34.                     info.add("用户登录失败,错误的用户名和密码!"); 
  35.                 } 
  36.             }catch(Exception e){ 
  37.                 e.printStackTrace(); 
  38.             } 
  39.           } 
  40.           req.setAttribute("info",info);//保存错误信息 
  41.           req.getRequestDispatcher(path).forward(req, resp);//跳转 
  42.         } 
  43.       public void doPost(HttpServletRequest req,HttpServletResponse resp) 
  44.                throws ServletException,IOException{ 
  45.           this.doGet(req, resp);//调用doGet()操作 
  46.       } 

 编写前台显示登录页login.jsp

  1. login.jsp 
  2. <%@ page language="java" contentType="text/html" pageEncoding="utf-8"%> 
  3. <%@ page import="java.util.*"%> 
  4. <html> 
  5. <head> 
  6. <title>登录页面</title> 
  7. <script language="javaScript"> 
  8.      function validate(f){ 
  9.          if(!(/^\w{5,15}$/.test(f.userid.value))){   
  10.              alert("用户ID必须是5~15位!"); 
  11.              f.userid.focus(); 
  12.              return false; 
  13.          } 
  14.          if(!(/^\w{5,15}$/.test(f.userpass.value))){ 
  15.              alert("密码必须是5~15位!"); 
  16.              f.userid.focus(); 
  17.              return false; 
  18.          } 
  19.          return true 
  20.      } 
  21. </script> 
  22. </head> 
  23. <body> 
  24. <h2>用户登录程序</h2> 
  25. <
  26.     request.setCharacterEncoding("utf-8"); 
  27. %> 
  28. <
  29.     List<String>info=(List<String>)request.getAttribute("info");//取得属性 
  30.     if(info!=null){   //判断是否有内容 
  31.         Iterator<String>iter=info.iterator();//  实例化Iterator 
  32.         while(iter.hasNext()){ 
  33. %> 
  34.              <h4><%=iter.next()%></h4> 
  35. <%           
  36.         } 
  37.     } 
  38. %> 
  39. <form action="LoginServlet" method="post" onSubmit="return validate(this)"> 
  40.        用户ID:<input type="text" name="userid"><br> 
  41.        密&nbsp;&nbsp;码:      <input type="password" name="userpass"><br> 
  42.        <input type="submit" value="登录"> 
  43.        <input type="reset" value="重置"> 
  44. </form> 
  45. </body> 
  46. </html> 

 不要忘记Servletweb.xml中的配置

  1. <servlet> 
  2.        <servlet-name>MVCLogin</servlet-name> 
  3.        <servlet-class>mvc.servlet.LoginServlet</servlet-class> 
  4.   </servlet> 
  5.   <servlet-mapping> 
  6.        <servlet-name>MVCLogin</servlet-name> 
  7.        <url-pattern>/jsp/LoginServlet</url-pattern> 
  8.   </servlet-mapping> 

注意:关于web.xml配置路径不会的同学可以到这儿去学习http://zhaoyuqiang.blog.51cto.com/6328846/1148434 

 写完所有的程序后来执行一下:效果如下下图所示:

Web开发模式【实例篇】MVC--迈向标准开发_MVC实例_07

Web开发模式【实例篇】MVC--迈向标准开发_WEB开发_08

Web开发模式【实例篇】MVC--迈向标准开发_modeII_09

Web开发模式【实例篇】MVC--迈向标准开发_modeII_10

 从这道程序中,可以发现这样一个问题,以前的JSP页面中的代码实在太多 ,但是现在的代码明显比以前少很多了,实际上对于一个JSP页面应该只包含如下的代码:

Web开发模式【实例篇】MVC--迈向标准开发_MVC实例_11

 一个好的JSP页面应该不导入任何一个开发包,当然,这要等到我们后面的学习了。

  明白了MVC的开发之后,我们来说一下他们之间的关系:

   MVC的实际开发作用,DAO只是负责数据的操作,JSP只是负责显示,Servlet只是负责接收参数,调用javaBean,并进行跳转功能。