實例: 用一個用戶登陸驗證明例講解MVC設計模式html
登陸程序以前已經學過,是使用JSP+JDBC完成的開發操做,可是以前的登陸程序開發中能夠發現有不少的問題,就是一個JSP文件中代碼過多了,即使是使用了JSP+javaBean的開發模式,其自己也存在JSP中代碼過多的問題。
如今咱們就能夠利用MVC設計模式來完全解決掉這些代碼過多的問題了mysql
在本程序中,用戶輸入的登陸信息提交給Servlet進行接收,Servlet接收到請求內容後首先對其合法性進行檢驗(若是輸入的內容是否爲空或者長度是否知足要求等),若是驗證失敗,則將錯誤信息傳遞給登陸頁顯示;若是數據合法,則調用DAO層完成數據庫的驗證,根據驗證的結構跳轉到登陸成功或登陸失敗的頁面。web
須要開發的頁面橄欖以下:sql
首先創建數據庫 (咱們用的數據庫是MySqL,不會的同窗能夠到這兒 http://zhaoyuqiang.blog.51cto.com/6328846/1127226)學習數據庫
建立數據庫,名字爲: 51ctomvctest 設計模式
建立表 , 名字爲: usermvc
設計表,以下:(注意紅色部分,不要忘記編碼,不然可能出現不能輸入中文現象)app
在表中填寫信息,以下圖所示:jsp
開發工具部署(咱們用的是MyEclipse)
部署以下圖所示:
導入sql的jar包文件,這個不用我再說了吧。
代碼編寫
按照DAO的設計標準,首先應該定義出VO類
- User.java
- //vo中的屬性與數據庫表中的屬性對應
- package mvc.vo;
- public class User {
- private String userid;
- private String name;
- private String password;
- public String getUserid(){
- return userid;
- }
- public void setUserid(String userid){
- this.userid=userid;
- }
- public String getPassword(){
- return password;
- }
- public void setPassword(String password){
- this.password=password;
- }
- public String getName(){
- return name;
- }
- public void setName(String name){
- this.name=name;
- }
- }
DAO中須要進行數據庫的鏈接操做,須要DatabaseConnection的類負責數據的操做
- DatabaseConnection.java
- //負責數據庫的打開與關閉操做
- package mvc.dbc;
- import java.sql.*;
- public class DatabaseConnection {
- private static final String DBdriver="org.gjt.mm.mysql.Driver";
- private static final String DBURL="jdbc:mysql://localhost:3306/51ctomvctest";
- private static final String DBUSER="root";
- private static final String DBPASS="425680992";
- private Connection conn=null;
- public DatabaseConnection()throws Exception{ //在構造方法中進行數據庫鏈接
- try{
- Class.forName(DBdriver);//加載驅動程序
- this.conn=DriverManager.getConnection(DBURL,DBUSER,DBPASS);//鏈接數據庫
- }catch(Exception e){
- throw e;
- }
- }
- public Connection getConnection(){//取得數據庫鏈接
- return this.conn;//取得數據鏈接
- }
- public void close()throws Exception{//關閉數據庫操做
- if(this.conn!=null){//避免NullPointerException
- try{
- this.conn.close();//關閉數據庫
- }catch(Exception e){
- throw e;
- }
- }
- }
- }
因爲本程序的核心功能是完成用戶登陸驗證,因此在定義DAO的時候,定義一個驗證方法
- IUserDAO.java
- //定義一個登錄驗證的方法,這個方法爲執行查詢操做,而且採用了findXxx()的命名形式
- package mvc.dao;
- import mvc.vo.User; //引用mvc.vo包裏面的User類
- public interface IUserDAO {
- /**
- * 用戶登陸驗證
- *@param user 傳入VO對象
- *@param 驗證的操做結果
- *@throw Exception
- */
- public boolean findLogin(User user)throws Exception;
- }
下面分別編寫實現類和代理類
- UserDAOImpl.java
- //定義實現類,在此類中將經過輸入用戶ID和密碼進行驗證,
- //若是驗證成功,則經過VO將用戶的真實姓名取出並返回
- package mvc.dao;
- import java.sql.*;
- import mvc.dao.IUserDAO;
- import mvc.vo.User;
- public class UserDAOImpl implements IUserDAO{
- private Connection conn=null;//定義數據庫鏈接對象
- private PreparedStatement pstmt=null;//定義數據庫鏈接對象
- public UserDAOImpl(Connection conn){//設置數據庫鏈接
- this.conn=conn;
- }
- public boolean findLogin(User user)throws Exception{
- boolean flag=false;
- try{
- String sql="select name from user where userid=? and password=?";
- thisthis.pstmt=this.conn.prepareStatement(sql);//實例化操做
- this.pstmt.setString(1,user.getUserid());//設置id
- this.pstmt.setString(2,user.getPassword());//設置密碼
- ResultSet rs=this.pstmt.executeQuery();//取得查詢結果
- if(rs.next()){
- user.setName(rs.getString(1));//取得姓名
- flag=true;//登陸成功
- }
- }catch(Exception e){
- throw e;
- }finally{
- if(this.pstmt!=null){
- try{
- this.pstmt.close();//關閉操做
- }catch(Exception e){
- throw e;
- }
- }
- }
- return flag;
- }
- }
- UserDAOProxy.java
- package mvc.dao;
- import mvc.dao.*;
- import mvc.dbc.*;
- import mvc.vo.*;
- public class UserDAOProxy implements IUserDAO{
- private DatabaseConnection dbc=null;//定義數據庫鏈接
- private IUserDAO dao=null;//定義DAO接口
- public UserDAOProxy(){
- try{
- this.dbc=new DatabaseConnection();//實例化數據庫鏈接
- }catch(Exception e){
- e.printStackTrace();
- }
- this.dao=new UserDAOImpl(this.dbc.getConnection());
- }
- public boolean findLogin(User user)throws Exception{
- boolean flag=false;
- try{
- flag=this.dao.findLogin(user);//調用真實主題
- }catch(Exception e){
- throw e;
- }finally{
- this.dbc.close();
- }
- return flag;
- }
- }
定義工廠類 取得DAO實例
- DAOFactory.java
- package mvc.factory;
- import mvc.dao.*;
- public class DAOFactory {
- public static IUserDAO getIUserDAOInstance(){//取得DAO實例
- return new UserDAOProxy();//返回代理實例
- }
- }
DAO的操做完成只是數據層的操做,下面須要編寫Servlet
- LoginServlet.java
- //定義Servlet,在Servlet中要接受客戶端發來的輸入數據
- //同時要調用DAO,而且要根據DAO的結果返回響應的信息
- //在Servlet中,首先定義對接受的userid和userpass兩個參數進行驗證,若是沒有輸入參數//或者是輸入的參數爲空,則會在info對象中增長相應的錯誤信息。
- //當驗證經過後,程序將調用DAO進行數據層的驗證,並根據DAO的返回結果來決定返回//給客戶端的信息
- package mvc.servlet;
- import java.io.*;
- import java.util.*;
- import javax.servlet.*;
- import javax.servlet.http.*;
- import mvc.factory.*;
- import mvc.vo.*;
- public class LoginServlet extends HttpServlet{
- public void doGet(HttpServletRequest req,HttpServletResponse resp)
- throws ServletException,IOException{
- String path="login.jsp";
- String userid=req.getParameter("userid");//接受userid內容
- String userpass=req.getParameter("userpass");//接受password內容
- List<String>info=new ArrayList<String>();//保存全部返回信息
- if(userid == null||"".equals(userid)){
- info.add("用麼id不能爲空!");
- }
- if(userpass==null||"".equals(userpass)){
- info.add("密碼不能爲空!");
- }
- if(info.size()==0){//用戶名和密碼驗證經過
- User user=new User();//實例化VO
- user.setUserid(userid);//設置userid
- user.setPassword(userpass);//設置password
- try{
- if(DAOFactory.getIUserDAOInstance().findLogin(user)){//驗證經過
- info.add("用戶登陸成功,歡迎"+user.getName()+"光臨!");
- }else{
- info.add("用戶登陸失敗,錯誤的用戶名和密碼!");
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- req.setAttribute("info",info);//保存錯誤信息
- req.getRequestDispatcher(path).forward(req, resp);//跳轉
- }
- public void doPost(HttpServletRequest req,HttpServletResponse resp)
- throws ServletException,IOException{
- this.doGet(req, resp);//調用doGet()操做
- }
- }
編寫前臺顯示登陸頁login.jsp
- login.jsp
- <%@ page language="java" contentType="text/html" pageEncoding="utf-8"%>
- <%@ page import="java.util.*"%>
- <html>
- <head>
- <title>登陸頁面</title>
- <script language="javaScript">
- function validate(f){
- if(!(/^\w{5,15}$/.test(f.userid.value))){
- alert("用戶ID必須是5~15位!");
- f.userid.focus();
- return false;
- }
- if(!(/^\w{5,15}$/.test(f.userpass.value))){
- alert("密碼必須是5~15位!");
- f.userid.focus();
- return false;
- }
- return true
- }
- </script>
- </head>
- <body>
- <h2>用戶登陸程序</h2>
- <%
- request.setCharacterEncoding("utf-8");
- %>
- <%
- List<String>info=(List<String>)request.getAttribute("info");//取得屬性
- if(info!=null){ //判斷是否有內容
- Iterator<String>iter=info.iterator();// 實例化Iterator
- while(iter.hasNext()){
- %>
- <h4><%=iter.next()%></h4>
- <%
- }
- }
- %>
- <form action="LoginServlet" method="post" onSubmit="return validate(this)">
- 用戶ID:<input type="text" name="userid"><br>
- 密 碼: <input type="password" name="userpass"><br>
- <input type="submit" value="登陸">
- <input type="reset" value="重置">
- </form>
- </body>
- </html>
不要忘記Servlet在web.xml中的配置
- <servlet>
- <servlet-name>MVCLogin</servlet-name>
- <servlet-class>mvc.servlet.LoginServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>MVCLogin</servlet-name>
- <url-pattern>/jsp/LoginServlet</url-pattern>
- </servlet-mapping>
注意:關於web.xml配置路徑不會的同窗能夠到這兒去學習http://zhaoyuqiang.blog.51cto.com/6328846/1148434
寫完全部的程序後來執行一下:效果以下下圖所示:
從這道程序中,能夠發現這樣一個問題,之前的JSP頁面中的代碼實在太多 ,可是如今的代碼明顯比之前少不少了,實際上對於一個JSP頁面應該只包含以下的代碼:
一個好的JSP頁面應該不導入任何一個開發包,固然,這要等到咱們後面的學習了。
明白了MVC的開發以後,咱們來講一下他們之間的關係:
MVC的實際開發做用,DAO只是負責數據的操做,JSP只是負責顯示,Servlet只是負責接收參數,調用javaBean,並進行跳轉功能。