Web開發模式【Mode I 和Mode II的介紹、應用案例】

開發模式的介紹

在Web開發模式中,有兩個主要的開發結構,稱爲模式一(Mode I)和模式二(Mode II).html

首先咱們來理清一些概念吧:java

  • DAO(Data Access Object):主要對數據的操做,增長、修改、刪除等原子性操做。
  • Web層:界面+控制器,也就是說JSP【界面】+Servlet【控制器】
  • Service業務層:將多個原子性的DAO操做進行組合,組合成一個完整的業務邏輯
  • 控制層:主要使用Servlet進行控制
  • 數據訪問層:使用DAO、Hibernate、JDBC技術實現對數據的增刪改查
  • JavaBean用於封裝數據,處理部分核心邏輯,每一層中都用到!

模式一

模式一指的就是在開發中將顯示層、控制層、數據層的操做統一交給JSP或者JavaBean來進行處理web

模式一有兩種狀況:數據庫

  • 徹底使用JSP作開發設計模式

    • 優勢:服務器

      1. 開發速度賊快,只要寫JSP就好了,JavaBean和Servlet都不用設計!
      2. 小幅度修改代碼方便,直接修改JSP頁面交給WEB容器就好了,不像Servlet還要編譯成.class文件再交給服務器!【固然了,在ide下開發這個也不算是事】
    • 缺點:微信

      1. 程序的可讀性差、複用性低、代碼複雜!什麼jsp代碼、html代碼都往上面寫,這確定很難閱讀,很難重用!
  • 使用JSP+JavaBean作開發dom

    • 優勢:jsp

      1. 程序的可讀性較高,大部分的代碼都寫在JavaBean上,不會和HTML代碼混合在一塊兒,可讀性還行的
      2. 可重複利用高,核心的代碼都由JavaBean開發了,JavaBean的設計就是用來重用、封裝,大大減小編寫重複代碼的工做!
    • 缺點:ide

      1. 沒有流程控制,程序中的JSP頁面都須要檢查請求的參數是否正確,異常發生時的處理。顯示操做和業務邏輯代碼工做會緊密耦合在一塊兒的!往後維護會困難

應用例子:

咱們使用JavaBean+JSP開發一個簡易的計算器吧,效果如圖下

  • 首先開發JavaBean對象
public class Calculator {
    
        private double firstNum;
        private double secondNum;
        private char Operator = '+';
        private double result;
    
    
        //JavaBean提供了計算的功能
        public void calculate() {
    
            switch (this.Operator) {
                case '+':
                    this.result = this.firstNum + this.secondNum;
                    break;
    
                case '-':
                    this.result = this.firstNum - this.secondNum;
                    break;
    
                case '*':
                    this.result = this.firstNum * this.secondNum;
                    break;
    
                case '/':
                    if (this.secondNum == 0) {
                        throw new RuntimeException("除數不能爲0");
                    }
                    this.result = this.firstNum / this.secondNum;
                    break;
    
                default:
                    throw new RuntimeException("傳入的字符非法!");
            }
        }
    
    
        public double getFirstNum() {
            return firstNum;
        }
    
        public void setFirstNum(double firstNum) {
            this.firstNum = firstNum;
        }
    
        public double getSecondNum() {
            return secondNum;
        }
    
        public void setSecondNum(double secondNum) {
            this.secondNum = secondNum;
        }
    
        public char getOperator() {
            return Operator;
        }
    
        public void setOperator(char operator) {
            Operator = operator;
        }
    
        public double getResult() {
            return result;
        }
    
        public void setResult(double result) {
            this.result = result;
        }
    }
  • 再開發顯示頁面
<%--開發用戶界面--%>
    <form action="/zhongfucheng/1.jsp" method="post">
        <table border="1">
            <tr>
                <td colspan="2">簡單計數器</td>
                <td></td>
            </tr>
            <tr>
                <td>第一個參數:</td>
                <td><input type="text" name="firstNum"></td>
            </tr>
            <tr>
                <td>運算符</td>
                <td>
                    <select name="operator">
                        <option value="+">+</option>
                        <option value="-">-</option>
                        <option value="*">*</option>
                        <option value="/">/</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td>第二個參數:</td>
                <td><input type="text " name="secondNum"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="提交"></td>
                <td></td>
            </tr>
        </table>
    </form>
  • 效果:

  • 獲取獲得顯示頁面提交的參數,調用JavaBean的方法,最後輸出結果!
<%--獲取獲得Bean對象--%>
    <jsp:useBean id="calculator" class="domain.Calculator" scope="page"/>
    
    <%--設置Bean對象的數據--%>
    <jsp:setProperty name="calculator" property="*"/>
    
    <%--調用Caculator的方法計算出值--%>
    <jsp:scriptlet>
        calculator.calculate();
    </jsp:scriptlet>
    
    
    <%--得出的結果:--%>
    
    <c:out value="計算得出的結果是:"/>
    <jsp:getProperty name="calculator" property="firstNum"/>
    <jsp:getProperty name="calculator" property="operator"/>
    <jsp:getProperty name="calculator" property="secondNum"/>
    <c:out value="="/>
    <jsp:getProperty name="calculator" property="result"/>
  • 效果:


開發這個簡易的計算器,只用了一個JSP頁面和一個JavaBean完成!

總的來講,Mode I 適合小型的開發,複雜程序低的開發,由於Mode I 的特色就是開發速度快,但在進行維護的時候就要付出更大的代價!


模式二

Mode II 中全部的開發都是以Servlet爲主體展開的,由Servlet接收全部的客戶端請求,而後根據請求調用相對應的JavaBean,並全部的顯示結果交給JSP完成!,也就是俗稱的MVC設計模式!

MVC設計模式:

  • 顯示層(View):主要負責接受Servlet傳遞的內容,調用JavaBean,將內容顯示給用戶
  • 控制層(Controller):主要負責全部用戶的請求參數,判斷請求參數是否合法,根據請求的類型調用JavaBean,將最終的處理結果交給顯示層顯示!
  • 模型層(Mode):模型層包括了業務層,DAO層。

應用例子:

咱們使用MVC模式開發一個簡單的用戶登錄註冊的案例吧!做爲一個簡單的用戶登錄註冊,這裏就直接使用XML文檔看成小型數據庫吧

①搭建開發環境

  • 導入相對應的開發包
  • 建立程序的包名
  • 建立xml文件,當作小型的數據庫

②開發實體User

private int id;
    private String username;
    private String password;
    private String email;
    private Date birthday;

    //....各類setter、getter

③開發dao

  • 這個根據業務來開發,咱們是登錄註冊,那應該提供什麼功能呢?註冊(外界傳遞一個User對象進來,我能夠在XML文檔多一條信息)。登錄(外界傳遞用戶名和密碼過來,我就在XML文檔中查找有沒該用戶名和密碼,若是有就返回一個User對象)
  • 3.1登錄功能
//外界傳遞用戶名和密碼進來,我要在XML文檔中查找是否有該條記錄
    public User find(String username, String password) {

        //獲得XML文檔的流對象
        InputStream inputStream = UserImplXML.class.getClassLoader().getResourceAsStream("user.xml");

        //獲得dom4j的解析器對象
        SAXReader saxReader = new SAXReader();


        try {

            //解析XML文檔
            Document document = saxReader.read(path);

            //使用XPATH技術,查找XML文檔中是否有傳遞進來的username和password
            Element element = (Element) document.selectSingleNode("//user[@username='" + username + "' and@password='" + password + "']");

            if (element == null) {
                return null;
            }

            //若是有,就把XML查出來的節點信息封裝到User對象,返回出去
            User user = new User();
            user.setId(Integer.parseInt(element.attributeValue("id")));
            user.setUsername(element.attributeValue("username"));
            user.setPassword(element.attributeValue("password"));
            user.setEmail(element.attributeValue("email"));

            //生日就須要轉換一下了,XML文檔保存的是字符串,User對象須要的是Date類型
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd");
            Date birthday = simpleDateFormat.parse(element.attributeValue("birthday"));
            user.setBirthday(birthday);

            //返回User對象出去
            return user;

        } catch (DocumentException e) {
            e.printStackTrace();
            throw new RuntimeException("初始化時候出錯啦!");
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException("查詢的時候出錯啦!");
        }

    }
  • 作完一個功能,最好就測試一下,看有沒有錯誤再繼續往下寫!
private String username = "zhongfucheng";
    private String password = "123";

    @Test
    public void testLogin() {

        UserImplXML userImplXML = new UserImplXML();
        User user = userImplXML.find(username, password);

        System.out.println(user.getBirthday());
        System.out.println(user.getEmail());
        System.out.println(user.getId());
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());


    }
  • 效果:


3.2註冊功能

//註冊功能,外界傳遞一個User對象進來。我就在XML文檔中添加一條信息
    public void register(User user) {

    //獲取XML文檔路徑!
    String path = UserImplXML.class.getClassLoader().getResource("user.xml").getPath();
        

        try {
            //獲取dom4j的解析器,解析XML文檔
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(path);

            //在XML文檔中建立新的節點
            Element newElement = DocumentHelper.createElement("user");
            newElement.addAttribute("id", String.valueOf(user.getId()));
            newElement.addAttribute("username", user.getUsername());
            newElement.addAttribute("email", user.getEmail());
            newElement.addAttribute("password", user.getPassword());

            //日期返回的是指定格式的日期
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd");
            String date = simpleDateFormat.format(user.getBirthday());
            newElement.addAttribute("birthday",date);

            //把新建立的節點增長到父節點上
            document.getRootElement().add(newElement);

            //把XML內容中文檔的內容寫到硬盤文件上
            OutputFormat outputFormat = OutputFormat.createPrettyPrint();
            outputFormat.setEncoding("UTF-8");
            XMLWriter xmlWriter = new XMLWriter(new FileWriter(path),outputFormat);
            xmlWriter.write(document);
            xmlWriter.close();

        } catch (DocumentException e) {
            e.printStackTrace();
            throw new RuntimeException("註冊的時候出錯了!!!");
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("註冊的時候出錯了!!!");
        }
    }
  • 咱們也測試一下有沒有錯誤!
@Test
    public void testRegister() {

        UserImplXML userImplXML = new UserImplXML();

        //這裏我爲了測試的方便,就添加一個帶5個參數的構造函數了!
        User user = new User(10, "nihao", "123", "sina@qq.com", new Date());

        userImplXML.register(user);
    }
  • 注意!測試的結果是在classes目錄下的user.xml文件查詢的!由於咱們是用Test來測試代碼,讀取XML文件時使用的是類裝載器的方法,在編譯後,按照WEB的結構目錄,XML文件的讀寫是在WEB-INF的classes目錄下的!


  • DAO的實現已經開發完成了,接下來咱們就對DAO的實現進行抽取。【固然了,也能夠先寫DAO再寫DAO的實現】


④開發service層

service層的開發就很是簡單了!上面已經說了,service層就是:將多個原子性的DAO操做進行組合,組合成一個完整的業務邏輯。簡單來講:對web層提供全部的業務服務的

在邏輯代碼不是很是複雜的狀況下,咱們能夠沒有service層的,這裏仍是演示一下吧!

public class UserServiceXML {
    
        //Service層就是調用Dao層的方法,咱們就直接在類中建立Dao層的對象了
        UserDao userImplXML = new UserImplXML();
    
        public void register(User user) {
            userImplXML.register(user);
        }
    
        public void login(String username, String password) {
    
            userImplXML.find(username, password);
        }
    }
  • 固然了,爲了更好的解耦,也把它抽取成接口


⑤開發web層

5.1咱們來先作註冊的界面吧!

  • 提供註冊界面的Servlet
public class RegisterUIServlet extends javax.servlet.http.HttpServlet {
        protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
    
            //直接跳轉到顯示註冊界面的JSP
            request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
    
        }
    
        protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
    
            this.doPost(request, response);
        }
    }
  • 開發註冊界面的JSP
<h1>歡迎來到註冊界面!</h1>

<%--提交給處理註冊的處理Servlet--%>

<form method="post" action="${pageContext.request.contextPath}/RegisterServlet">

    <table>
        <%--對於id來說,是服務器分配的!不須要用戶本身輸入--%>
        <tr>
            <td>用戶名</td>
            <td>
                <input type="text " name="username">
            </td>
        </tr>
        <tr>
            <td>密碼</td>
            <td>
                <input type="text" name="password">
            </td>
        </tr>
        <tr>
            <td>確認密碼</td>
            <td>
                <input type="text" name="password">
            </td>
        </tr>
        <tr>
            <td>郵箱</td>
            <td>
                <input type="text" name="email">
            </td>
        </tr>
        <tr>
            <td>生日</td>
            <td>
                <input type="text " name="birethday">
            </td>
        </tr>
        <tr>
            <td>
                <input type="submit" value="提交">
            </td>
            <td>
                <input type="reset" value="重置!">
            </td>
        </tr>
    </table>
</form>
  • JSP頁面是這樣子的

  • 接下來,咱們要開發處理用戶註冊提交的Servlet
//首先要接受Parameter的參數,封裝到User裏面去
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //......若是參數過多,咱們就要寫好多好多相似的代碼了...
  • 此時,咱們應該想起反射機制中的BeanUtils開發包..爲了更好地重用,我就將它寫成一個工具類
/*
    * 將Parameter參數的數據封裝到Bean中,爲了外邊不用強轉,這裏就使用泛型了!
    *
    * @request   因爲要獲取的是Parameter參數的信息,因此須要有request對象
    * @tClass    自己是不知道封裝什麼對象的,因此用class
    *
    * */

    public static <T> T request2Bean(HttpServletRequest httpServletRequest, Class<T> tClass) {

        try {

            //建立tClass的對象
            T bean = tClass.newInstance();

            //獲取獲得Parameter中所有的參數的名字
            Enumeration enumeration = httpServletRequest.getParameterNames();

            //遍歷上邊獲取獲得的集合
            while (enumeration.hasMoreElements()) {

                //獲取獲得每個帶過來參數的名字
                String name = (String) enumeration.nextElement();

                //獲取獲得值
                String value = httpServletRequest.getParameter(name);

                //把數據封裝到Bean對象中
                BeanUtils.setProperty(bean, name, value);
            }
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("封裝數據到Bean對象中出錯了!");
        }
    }
  • 通過咱們測試,日期不能直接封裝到Bean對象中,會直接報出異常

  • 對於日期而言,須要一個日期轉換器。當BeanUtils的setProperty()方法檢測到日期時,會自動調用日期轉換器對日期進行轉換,從而實現封裝!
  • 因而乎,就在上面的方法中添加如下一句代碼
//日期轉換器
            ConvertUtils.register(new DateLocaleConverter(), Date.class);

  • 還有一個問題,用戶的id不是本身輸入的,是由程序生成的。咱們避免id的重複,就使用UUID生成用戶的id吧!爲了更好的重用,咱們也把它封裝成一個方法!
/*生成ID*/
    public static int makeId() {
        return Integer.parseInt(UUID.randomUUID().toString());
    }
  • 好的,咱們來測試一下吧!如下是RegisterServlet的代碼
User user = WebUtils.request2Bean(request, User.class);
        user.setId(WebUtils.makeId());

        //調用service層的註冊方法,實現註冊
        ServiceBussiness serviceBussiness = new UserServiceXML();
        serviceBussiness.register(user);
  • 效果:


上面的代碼是不夠完善的(沒有校驗用戶輸入的信息、註冊成功或失敗都沒有給出提示..等等)

  • 下面,咱們來校驗用戶輸入的信息吧,若是用戶輸入的信息不合法,就直接跳轉回註冊的界面
  • 剛纔咱們是用BeanUtils把Parameter的信息所有直接封裝到User對象中,但如今我想要驗證用戶提交表單的數據,也應該把表單的數據用一個對象保存着【面向對象的思想、封裝、重用】
  • 流程是這樣子的:當用戶提交表單數據的時候,就把表單數據封裝到咱們設計的表單對象上,調用表單對象的方法,驗證數據是否合法
  • 好了,咱們來開發一個表單的對象吧,最重要的是怎麼填寫validate()方法!
public class FormBean {

    //表單提交過來的數據全都是String類型的,birthday也不例外!
    private String username;
    private String password;
    private String password2;
    private String email;
    private String birthday;
    
    /*用於判斷表單提交過來的數據是否合法*/
    public boolean validate() {
        
        return false;
        
    }
    
    //......各類setter、getter方法
}
  • 如下是我定下的規則:

  • 方法的代碼以下:
public boolean validate() {

        //用戶名不能爲空,而且要是3-8的字符 abcdABcd
        if (this.username == null || this.username.trim().equals("")) {
            return false;

        } else {
            if (!this.username.matches("[a-zA-Z]{3,8}")) {
                return false;
            }
        }

        //密碼不能爲空,而且要是3-8的數字
        if (this.password == null || this.password.trim().equals("")) {
            return false;
        } else {
            if (!this.password.matches("\\d{3,8}")) {
                return false;
            }
        }

        //兩次密碼要一致
        if (this.password2 != null && !this.password2.trim().equals("")) {
            if (!this.password2.equals(this.password)) {
                return false;
            }
        }

        //郵箱能夠爲空,若是爲空就必須合法
            if (this.email != null && !this.email.trim().equals("")) {
                if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) {

                    System.out.println("郵箱錯誤了!");
                    return false;
                }
        }

        //日期能夠爲空,若是爲空就必須合法
        if (this.birthday != null && !this.birthday.trim().equals("")) {

            try {
                DateLocaleConverter dateLocaleConverter = new DateLocaleConverter();
                dateLocaleConverter.convert(this.birthday);
            } catch (Exception e) {

                System.out.println("日期錯誤了!");
                return false;
            }
        }

        
        //若是上面都沒有執行,那麼就是合法的了,返回true
        return true;
    }
  • 處理表單數據的Servlet,代碼是這樣子的
//將表單的數據封裝到formBean中
        FormBean formBean = WebUtils.request2Bean(request, FormBean.class);

        //驗證表單的數據是否合法,若是不合法就跳轉回去註冊的頁面
        if(formBean.validate()==false){
            request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
            return;
        }
        try {
            
            //將表單的數據封裝到User對象中
            User user = WebUtils.request2Bean(request, User.class);
            user.setId(WebUtils.makeId());

            //調用service層的註冊方法,實現註冊
            ServiceBussiness serviceBussiness = new UserServiceXML();
            serviceBussiness.register(user);

        } catch (Exception e) {
            e.printStackTrace();
        }
  • 接下來咱們測試一下吧!將全部的信息都按照規定的輸入!

  • 沒有問題!已經將記錄寫到XML文件上了!

  • 可是,若是我沒有輸入日期呢

它拋出了錯誤!緣由也很是簡單:表單數據提交給Servlet,Servlet將表單的數據(Parameter中的數據)用BeanUtils封裝到User對象中,當封裝到日期的時候,發現日期爲null,沒法轉換成日期對象!

那咱們如今要怎麼解決呢?

首先咱們要明確:由於咱們在設定的時候,已經容許了email和birthday能夠爲空,那麼在DAO層就應該有相應的邏輯判斷email和birthday是否爲空

if (user.getEmail() == null) {
                newElement.addAttribute("email", "");
            } else {
                newElement.addAttribute("email", user.getEmail());

            }

            //若是不是空才格式化信息
            if (user.getBirthday() != null) {

                //日期返回的是指定格式的日期
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                String date = simpleDateFormat.format(user.getBirthday());
                
                newElement.addAttribute("birthday", date);
            } else {
                newElement.addAttribute("birthday", "");
            }

解決辦法:

  • Parameter中的數據若是是"",我就不把數據封裝到User對象中,執行下一次循環!
public static <T> T request2Bean(HttpServletRequest httpServletRequest, Class<T> tClass) {

        try {

            //建立tClass的對象
            T bean = tClass.newInstance();

            //獲取獲得Parameter中所有的參數的名字
            Enumeration enumeration = httpServletRequest.getParameterNames();

            //日期轉換器
            ConvertUtils.register(new DateLocaleConverter(), Date.class);

            //遍歷上邊獲取獲得的集合
            while (enumeration.hasMoreElements()) {

                //獲取獲得每個帶過來參數的名字
                String name = (String) enumeration.nextElement();

                //獲取獲得值
                String value = httpServletRequest.getParameter(name);

                //若是Parameter中的數據爲"",那麼我就不封裝到User對象裏邊去!執行下一次循環
                if (value == "") {
                    continue;
                } else {
                    //把數據封裝到Bean對象中
                    BeanUtils.setProperty(bean, name, value);
                }

            }
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("封裝數據到Bean對象中出錯了!");
        }
    }
  • 效果:

將數據封裝到User對象中還有另一個辦法:

  • 咱們知道BeanUtils有個copyProperties()方法,能夠將某個對象的成員數據拷貝到另一個對象的成員變量數據上(前提是成員變量的名稱相同!)咱們FormBean對象的成員變量名稱和User對象的成員變量的名稱是一致的!而且,前面在驗證的時候,咱們已經把Parameter中帶過來的數據封裝到了FormBean對象中了,因此咱們可使用copyProperties()方法!
  • 使用該方法時,值得注意的是:第一個參數是拷貝到哪個對象上(也就是User對象),第二個參數是被拷貝的對象(也就是formbean對象),口訣:後拷前....不要搞混了!!!!!(我就是搞混了,弄了好久...)


  • 處理表單的Servlet完整代碼以下
//將表單的數據封裝到formBean中
        FormBean formBean = WebUtils.request2Bean(request, FormBean.class);

        //驗證表單的數據是否合法,若是不合法就跳轉回去註冊的頁面
        if(formBean.validate()==false){
            request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
            return;
        }
        try {

            //這是第一種--------------------------
          /*User user = new User();
            user.setId(WebUtils.makeId());
            BeanUtils.copyProperties(user,formBean);*/
            //------------------------------------------

            //這是第二種
            User user1 = WebUtils.request2Bean(request,User.class);
            user1.setId(WebUtils.makeId());
            //-----------------------------------


            //調用service層的註冊方法,實現註冊
            ServiceBussiness serviceBussiness = new UserServiceXML();
            serviceBussiness.register(user1);

        } catch (Exception e) {
            e.printStackTrace();
        }

如今還有問題,若是我填寫信息不合法,提交給服務器驗證之後,服務器應該告訴用戶哪一個信息不合法,而不是直接把跳轉回註冊界面,把全部的信息所有清空,讓用戶從新填寫!

咱們應該這樣作:當發現用戶輸入的信息不合法時,把錯誤的信息記錄下來,等到返回註冊頁面,就提示用戶哪裏出錯了!

  • 在FormBean對象中添加一個HashMap集合(由於等會還要根據關鍵字把錯誤信息顯示給用戶!)
  • FormBean的所有代碼以下:
//表單提交過來的數據全都是String類型的,birthday也不例外!
    private String username;
    private String password;
    private String password2;
    private String email;
    private String birthday;

    //記錄錯誤的信息
    private HashMap<String, String> error = new HashMap<>();
    
    
    /*用於判斷表單提交過來的數據是否合法*/
    public boolean validate() {

        //用戶名不能爲空,而且要是3-8的字符 abcdABcd
        if (this.username == null || this.username.trim().equals("")) {

            error.put("username", "用戶名不能爲空,而且要是3-8的字符");
            return false;

        } else {
            if (!this.username.matches("[a-zA-Z]{3,8}")) {
                error.put("username", "用戶名不能爲空,而且要是3-8的字符");
                return false;
            }
        }

        //密碼不能爲空,而且要是3-8的數字
        if (this.password == null || this.password.trim().equals("")) {
            error.put("password", "密碼不能爲空,而且要是3-8的數字");
            return false;
        } else {
            if (!this.password.matches("\\d{3,8}")) {
                error.put("password", "密碼不能爲空,而且要是3-8的數字");
                return false;
            }
        }

        //兩次密碼要一致
        if (this.password2 != null && !this.password2.trim().equals("")) {
            if (!this.password2.equals(this.password)) {
                error.put("password2", "兩次密碼要一致");
                return false;
            }
        }

        //郵箱能夠爲空,若是爲空就必須合法
            if (this.email != null && !this.email.trim().equals("")) {
                if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) {

                    error.put("email", "郵箱不合法!");
                    return false;
                }
        }

        //日期能夠爲空,若是爲空就必須合法
        if (this.birthday != null && !this.birthday.trim().equals("")) {

            try {
                DateLocaleConverter dateLocaleConverter = new DateLocaleConverter();
                dateLocaleConverter.convert(this.birthday);
            } catch (Exception e) {

                error.put("birthday", "日期不合法!");
                return false;
            }
        }

        //若是上面都沒有執行,那麼就是合法的了,返回true
        return true;
    }

    //.....各類的setter和getter
  • 在跳轉到註冊頁面以前,把formbean對象存到request域中。在註冊頁面就能夠把錯誤的信息取出來(使用EL表達式)!
  • 處理表單的Servlet的部分代碼
//驗證表單的數據是否合法,若是不合法就跳轉回去註冊的頁面
        if(formBean.validate()==false){

            //在跳轉以前,把formbean對象傳遞給註冊頁面
            request.setAttribute("formbean", formBean);
            request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
            return;
        }
  • 在註冊頁面中,使用EL表達式把錯誤的信息寫出來

  • 測試:

  • 效果:


作到這裏,仍是有丟丟的問題,咱們不該該把用戶輸入的數據所有清空的!你想一想,若是用戶註冊須要輸入多個信息,僅僅一個出錯了,就把所有信息清空,要他從新填寫,這樣是不合理的!

  • 咱們在各個的輸入項中使用EL表達式回顯數據就好了

  • 效果:


尚未完善,細心的朋友能夠發現,上面圖的日期也是錯誤的,可是沒一次性標記出來給用戶!要改也十分簡單:在驗證的時候,不要先急着return false 用一個布爾型變量記住,最後返回布爾型的變量便可


不管註冊成功仍是失敗都須要給用戶一個友好界面的!

5.2登錄界面

登錄和註冊是相似的,咱們按着註冊的步驟來寫就對了!

首先寫一個提供登錄界面的Servlet

//直接跳轉到登錄界面
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
  • 寫登錄界面
<h1>這是登錄界面</h1>

<form action="${pageContext.request.contextPath}/LoginServlet" method="post">
    <table>
        <tr>
            <td>用戶名</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>密碼</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td><input type="submit" value="提交"></td>
            <td><input type="reset" name="重置"></td>
        </tr>
    </table>
</form>
  • 寫處理登錄表單的Servlet
//獲取提交過來的數據
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //調用service層的方法,去查詢數據庫(XML)是否有該條記錄
        try {
            ServiceBussiness serviceBussiness = new UserServiceXML();
            User user = serviceBussiness.login(username, password);

            if (user == null) {
                request.setAttribute("message", "用戶名或密碼是錯的");
            } else {
                request.setAttribute("message","登錄成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("message","登錄失敗咯");
        }
        request.getRequestDispatcher("/message.jsp").forward(request, response);
  • 效果:


5.3把註冊和登錄都掛在首頁上

<h1>這是首頁!</h1>

  <a href="${pageContext.request.contextPath}/LoginUIServlet">登錄</a>
  <a href="${pageContext.request.contextPath}/RegisterUIServlet">註冊</a>
  </body>

總結

  • 使用JSP+JavaBean開發一個簡單計算器,是很是容易的,顯示頁面和請求都是交由JSP來作。沒有什麼新的知識點,用一些JSP行爲就能完成了。
  • MVC模式開發使用Servlet來作處理請求,代碼量略大,但層次清晰
  • 使用BeanUtils開發組件能夠將request請求的參數封裝到JavaBean對象中,Date屬性要另外處理
  • 校驗的功能也是使用一個JavaBean來完成,目的就是爲了可重用性,職責分工。同時,咱們能夠在該JavaBean設置一個Map集合來保存錯誤的信息,以便在前臺上展現錯誤信息。
若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章的同窗,能夠關注微信公衆號: Java3y
相關文章
相關標籤/搜索