成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Web開發(fā)模式【Mode I 和Mode II的介紹、應(yīng)用案例】

longmon / 2903人閱讀

摘要:開發(fā)模式的介紹在開發(fā)模式中,有兩個(gè)主要的開發(fā)結(jié)構(gòu),稱為模式一和模式二首先我們來理清一些概念吧主要對(duì)數(shù)據(jù)的操作,增加修改刪除等原子性操作。

開發(fā)模式的介紹

在Web開發(fā)模式中,有兩個(gè)主要的開發(fā)結(jié)構(gòu),稱為模式一(Mode I)和模式二(Mode II).

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

DAO(Data Access Object):主要對(duì)數(shù)據(jù)的操作,增加、修改、刪除等原子性操作。

Web層:界面+控制器,也就是說JSP【界面】+Servlet【控制器】

Service業(yè)務(wù)層:將多個(gè)原子性的DAO操作進(jìn)行組合,組合成一個(gè)完整的業(yè)務(wù)邏輯

控制層:主要使用Servlet進(jìn)行控制

數(shù)據(jù)訪問層:使用DAO、Hibernate、JDBC技術(shù)實(shí)現(xiàn)對(duì)數(shù)據(jù)的增刪改查

JavaBean用于封裝數(shù)據(jù),處理部分核心邏輯,每一層中都用到!

模式一

模式一指的就是在開發(fā)中將顯示層、控制層、數(shù)據(jù)層的操作統(tǒng)一交給JSP或者JavaBean來進(jìn)行處理!

模式一有兩種情況:

完全使用JSP做開發(fā)

優(yōu)點(diǎn):

開發(fā)速度賊快,只要寫JSP就行了,JavaBean和Servlet都不用設(shè)計(jì)!

小幅度修改代碼方便,直接修改JSP頁(yè)面交給WEB容器就行了,不像Servlet還要編譯成.class文件再交給服務(wù)器!【當(dāng)然了,在ide下開發(fā)這個(gè)也不算是事】

缺點(diǎn):

程序的可讀性差、復(fù)用性低、代碼復(fù)雜!什么jsp代碼、html代碼都往上面寫,這肯定很難閱讀,很難重用!

使用JSP+JavaBean做開發(fā)

優(yōu)點(diǎn):

程序的可讀性較高,大部分的代碼都寫在JavaBean上,不會(huì)和HTML代碼混合在一起,可讀性還行的。

可重復(fù)利用高,核心的代碼都由JavaBean開發(fā)了,JavaBean的設(shè)計(jì)就是用來重用、封裝,大大減少編寫重復(fù)代碼的工作!

缺點(diǎn):

沒有流程控制,程序中的JSP頁(yè)面都需要檢查請(qǐng)求的參數(shù)是否正確,異常發(fā)生時(shí)的處理。顯示操作和業(yè)務(wù)邏輯代碼工作會(huì)緊密耦合在一起的!日后維護(hù)會(huì)困難

應(yīng)用例子:

我們使用JavaBean+JSP開發(fā)一個(gè)簡(jiǎn)易的計(jì)算器吧,效果如圖下

首先開發(fā)JavaBean對(duì)象

    public class Calculator {
    
        private double firstNum;
        private double secondNum;
        private char Operator = "+";
        private double result;
    
    
        //JavaBean提供了計(jì)算的功能
        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("除數(shù)不能為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;
        }
    }

再開發(fā)顯示頁(yè)面

    <%--開發(fā)用戶界面--%>
    
簡(jiǎn)單計(jì)數(shù)器
第一個(gè)參數(shù):
運(yùn)算符
第二個(gè)參數(shù):

效果:

獲取得到顯示頁(yè)面提交的參數(shù),調(diào)用JavaBean的方法,最后輸出結(jié)果!

    <%--獲取得到Bean對(duì)象--%>
    
    
    <%--設(shè)置Bean對(duì)象的數(shù)據(jù)--%>
    
    
    <%--調(diào)用Caculator的方法計(jì)算出值--%>
    
        calculator.calculate();
    
    
    
    <%--得出的結(jié)果:--%>
    
    
    
    
    
    
    

效果:

開發(fā)這個(gè)簡(jiǎn)易的計(jì)算器,只用了一個(gè)JSP頁(yè)面和一個(gè)JavaBean完成!

總的來說,Mode I 適合小型的開發(fā),復(fù)雜程序低的開發(fā),因?yàn)镸ode I 的特點(diǎn)就是開發(fā)速度快,但在進(jìn)行維護(hù)的時(shí)候就要付出更大的代價(jià)!

模式二

Mode II 中所有的開發(fā)都是以Servlet為主體展開的,由Servlet接收所有的客戶端請(qǐng)求,然后根據(jù)請(qǐng)求調(diào)用相對(duì)應(yīng)的JavaBean,并所有的顯示結(jié)果交給JSP完成!,也就是俗稱的MVC設(shè)計(jì)模式!

MVC設(shè)計(jì)模式:

顯示層(View):主要負(fù)責(zé)接受Servlet傳遞的內(nèi)容,調(diào)用JavaBean,將內(nèi)容顯示給用戶

控制層(Controller):主要負(fù)責(zé)所有用戶的請(qǐng)求參數(shù),判斷請(qǐng)求參數(shù)是否合法,根據(jù)請(qǐng)求的類型調(diào)用JavaBean,將最終的處理結(jié)果交給顯示層顯示!

模型層(Mode):模型層包括了業(yè)務(wù)層,DAO層。

應(yīng)用例子:

我們使用MVC模式開發(fā)一個(gè)簡(jiǎn)單的用戶登陸注冊(cè)的案例吧!作為一個(gè)簡(jiǎn)單的用戶登陸注冊(cè),這里就直接使用XML文檔當(dāng)作小型數(shù)據(jù)庫(kù)吧!

①搭建開發(fā)環(huán)境

導(dǎo)入相對(duì)應(yīng)的開發(fā)包

創(chuàng)建程序的包名

創(chuàng)建xml文件,當(dāng)做小型的數(shù)據(jù)庫(kù)

②開發(fā)實(shí)體User

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

    //....各種setter、getter

③開發(fā)dao

這個(gè)根據(jù)業(yè)務(wù)來開發(fā),我們是登陸注冊(cè),那應(yīng)該提供什么功能呢?注冊(cè)(外界傳遞一個(gè)User對(duì)象進(jìn)來,我可以在XML文檔多一條信息)。登陸(外界傳遞用戶名和密碼過來,我就在XML文檔中查找有沒該用戶名和密碼,如果有就返回一個(gè)User對(duì)象)

3.1登陸功能

    //外界傳遞用戶名和密碼進(jìn)來,我要在XML文檔中查找是否有該條記錄
    public User find(String username, String password) {

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

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


        try {

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

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

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

            //如果有,就把XML查出來的節(jié)點(diǎn)信息封裝到User對(duì)象,返回出去
            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"));

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

            //返回User對(duì)象出去
            return user;

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

    }

做完一個(gè)功能,最好就測(cè)試一下,看有沒有錯(cuò)誤再繼續(xù)往下寫!


    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注冊(cè)功能


    //注冊(cè)功能,外界傳遞一個(gè)User對(duì)象進(jìn)來。我就在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文檔中創(chuàng)建新的節(jié)點(diǎn)
            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);

            //把新創(chuàng)建的節(jié)點(diǎn)增加到父節(jié)點(diǎn)上
            document.getRootElement().add(newElement);

            //把XML內(nèi)容中文檔的內(nèi)容寫到硬盤文件上
            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("注冊(cè)的時(shí)候出錯(cuò)了?。。?);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("注冊(cè)的時(shí)候出錯(cuò)了?。?!");
        }
    }

我們也測(cè)試一下有沒有錯(cuò)誤!


    @Test
    public void testRegister() {

        UserImplXML userImplXML = new UserImplXML();

        //這里我為了測(cè)試的方便,就添加一個(gè)帶5個(gè)參數(shù)的構(gòu)造函數(shù)了!
        User user = new User(10, "nihao", "123", "sina@qq.com", new Date());

        userImplXML.register(user);
    }

注意!測(cè)試的結(jié)果是在classes目錄下的user.xml文件查詢的!因?yàn)?strong>我們是用Test來測(cè)試代碼,讀取XML文件時(shí)使用的是類裝載器的方法,在編譯后,按照WEB的結(jié)構(gòu)目錄,XML文件的讀寫是在WEB-INF的classes目錄下的!

DAO的實(shí)現(xiàn)已經(jīng)開發(fā)完成了,接下來我們就對(duì)DAO的實(shí)現(xiàn)進(jìn)行抽取。【當(dāng)然了,也可以先寫DAO再寫DAO的實(shí)現(xiàn)】

④開發(fā)service層

service層的開發(fā)就非常簡(jiǎn)單了!上面已經(jīng)說了,service層就是:將多個(gè)原子性的DAO操作進(jìn)行組合,組合成一個(gè)完整的業(yè)務(wù)邏輯。簡(jiǎn)單來說:對(duì)web層提供所有的業(yè)務(wù)服務(wù)的!

在邏輯代碼不是非常復(fù)雜的情況下,我們可以沒有service層的,這里還是演示一下吧!


    public class UserServiceXML {
    
        //Service層就是調(diào)用Dao層的方法,我們就直接在類中創(chuàng)建Dao層的對(duì)象了
        UserDao userImplXML = new UserImplXML();
    
        public void register(User user) {
            userImplXML.register(user);
        }
    
        public void login(String username, String password) {
    
            userImplXML.find(username, password);
        }
    }

當(dāng)然了,為了更好的解耦,也把它抽取成接口!

⑤開發(fā)web層 5.1我們來先做注冊(cè)的界面吧!

提供注冊(cè)界面的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 {
    
            //直接跳轉(zhuǎn)到顯示注冊(cè)界面的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);
        }
    }

開發(fā)注冊(cè)界面的JSP

歡迎來到注冊(cè)界面!

<%--提交給處理注冊(cè)的處理Servlet--%>
<%--對(duì)于id來講,是服務(wù)器分配的!不需要用戶自己輸入--%>
用戶名
密碼
確認(rèn)密碼
郵箱
生日

JSP頁(yè)面是這樣子的

接下來,我們要開發(fā)處理用戶注冊(cè)提交的Servlet

        //首先要接受Parameter的參數(shù),封裝到User里面去
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //......如果參數(shù)過多,我們就要寫好多好多類似的代碼了...

此時(shí),我們應(yīng)該想起反射機(jī)制中的BeanUtils開發(fā)包..為了更好地重用,我就將它寫成一個(gè)工具類!


    /*
    * 將Parameter參數(shù)的數(shù)據(jù)封裝到Bean中,為了外邊不用強(qiáng)轉(zhuǎn),這里就使用泛型了!
    *
    * @request   由于要獲取的是Parameter參數(shù)的信息,所以需要有request對(duì)象
    * @tClass    本身是不知道封裝什么對(duì)象的,所以用class
    *
    * */

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

        try {

            //創(chuàng)建tClass的對(duì)象
            T bean = tClass.newInstance();

            //獲取得到Parameter中全部的參數(shù)的名字
            Enumeration enumeration = httpServletRequest.getParameterNames();

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

                //獲取得到每一個(gè)帶過來參數(shù)的名字
                String name = (String) enumeration.nextElement();

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

                //把數(shù)據(jù)封裝到Bean對(duì)象中
                BeanUtils.setProperty(bean, name, value);
            }
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("封裝數(shù)據(jù)到Bean對(duì)象中出錯(cuò)了!");
        }
    }

經(jīng)過我們測(cè)試,日期不能直接封裝到Bean對(duì)象中,會(huì)直接報(bào)出異常!

對(duì)于日期而言,需要一個(gè)日期轉(zhuǎn)換器。當(dāng)BeanUtils的setProperty()方法檢測(cè)到日期時(shí),會(huì)自動(dòng)調(diào)用日期轉(zhuǎn)換器對(duì)日期進(jìn)行轉(zhuǎn)換,從而實(shí)現(xiàn)封裝!

于是乎,就在上面的方法中添加以下一句代碼

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

還有一個(gè)問題,用戶的id不是自己輸入的,是由程序生成的。我們避免id的重復(fù),就使用UUID生成用戶的id吧!為了更好的重用,我們也把它封裝成一個(gè)方法!


    /*生成ID*/
    public static int makeId() {
        return Integer.parseInt(UUID.randomUUID().toString());
    }

好的,我們來測(cè)試一下吧!以下是RegisterServlet的代碼

        User user = WebUtils.request2Bean(request, User.class);
        user.setId(WebUtils.makeId());

        //調(diào)用service層的注冊(cè)方法,實(shí)現(xiàn)注冊(cè)
        ServiceBussiness serviceBussiness = new UserServiceXML();
        serviceBussiness.register(user);

效果:

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

下面,我們來校驗(yàn)用戶輸入的信息吧,如果用戶輸入的信息不合法,就直接跳轉(zhuǎn)回注冊(cè)的界面。

剛才我們是用BeanUtils把Parameter的信息全部直接封裝到User對(duì)象中,但現(xiàn)在我想要驗(yàn)證用戶提交表單的數(shù)據(jù),也應(yīng)該把表單的數(shù)據(jù)用一個(gè)對(duì)象保存著【面向?qū)ο蟮乃枷?、封裝、重用】

流程是這樣子的:當(dāng)用戶提交表單數(shù)據(jù)的時(shí)候,就把表單數(shù)據(jù)封裝到我們?cè)O(shè)計(jì)的表單對(duì)象上,調(diào)用表單對(duì)象的方法,驗(yàn)證數(shù)據(jù)是否合法!

好了,我們來開發(fā)一個(gè)表單的對(duì)象吧,最重要的是怎么填寫validate()方法!

public class FormBean {

    //表單提交過來的數(shù)據(jù)全都是String類型的,birthday也不例外!
    private String username;
    private String password;
    private String password2;
    private String email;
    private String birthday;
    
    /*用于判斷表單提交過來的數(shù)據(jù)是否合法*/
    public boolean validate() {
        
        return false;
        
    }
    
    //......各種setter、getter方法
}

以下是我定下的規(guī)則:

方法的代碼如下:

    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的數(shù)字
        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("郵箱錯(cuò)誤了!");
                    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("日期錯(cuò)誤了!");
                return false;
            }
        }

        
        //如果上面都沒有執(zhí)行,那么就是合法的了,返回true
        return true;
    }

處理表單數(shù)據(jù)的Servlet,代碼是這樣子的


        //將表單的數(shù)據(jù)封裝到formBean中
        FormBean formBean = WebUtils.request2Bean(request, FormBean.class);

        //驗(yàn)證表單的數(shù)據(jù)是否合法,如果不合法就跳轉(zhuǎn)回去注冊(cè)的頁(yè)面
        if(formBean.validate()==false){
            request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
            return;
        }
        try {
            
            //將表單的數(shù)據(jù)封裝到User對(duì)象中
            User user = WebUtils.request2Bean(request, User.class);
            user.setId(WebUtils.makeId());

            //調(diào)用service層的注冊(cè)方法,實(shí)現(xiàn)注冊(cè)
            ServiceBussiness serviceBussiness = new UserServiceXML();
            serviceBussiness.register(user);

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

接下來我們測(cè)試一下吧!將所有的信息都按照規(guī)定的輸入!

沒有問題!已經(jīng)將記錄寫到XML文件上了!

但是,如果我沒有輸入日期呢?

它拋出了錯(cuò)誤!原因也非常簡(jiǎn)單:表單數(shù)據(jù)提交給Servlet,Servlet將表單的數(shù)據(jù)(Parameter中的數(shù)據(jù))用BeanUtils封裝到User對(duì)象中,當(dāng)封裝到日期的時(shí)候,發(fā)現(xiàn)日期為null,無法轉(zhuǎn)換成日期對(duì)象!

那我們現(xiàn)在要怎么解決呢?

首先我們要明確:因?yàn)?strong>我們?cè)谠O(shè)定的時(shí)候,已經(jīng)允許了email和birthday可以為空,那么在DAO層就應(yīng)該有相應(yīng)的邏輯判斷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中的數(shù)據(jù)如果是"",我就不把數(shù)據(jù)封裝到User對(duì)象中,執(zhí)行下一次循環(huán)!

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

        try {

            //創(chuàng)建tClass的對(duì)象
            T bean = tClass.newInstance();

            //獲取得到Parameter中全部的參數(shù)的名字
            Enumeration enumeration = httpServletRequest.getParameterNames();

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

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

                //獲取得到每一個(gè)帶過來參數(shù)的名字
                String name = (String) enumeration.nextElement();

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

                //如果Parameter中的數(shù)據(jù)為"",那么我就不封裝到User對(duì)象里邊去!執(zhí)行下一次循環(huán)
                if (value == "") {
                    continue;
                } else {
                    //把數(shù)據(jù)封裝到Bean對(duì)象中
                    BeanUtils.setProperty(bean, name, value);
                }

            }
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("封裝數(shù)據(jù)到Bean對(duì)象中出錯(cuò)了!");
        }
    }

效果:

將數(shù)據(jù)封裝到User對(duì)象中還有另外一個(gè)辦法:

我們知道BeanUtils有個(gè)copyProperties()方法,可以將某個(gè)對(duì)象的成員數(shù)據(jù)拷貝到另外一個(gè)對(duì)象的成員變量數(shù)據(jù)上(前提是成員變量的名稱相同?。?/strong>我們FormBean對(duì)象的成員變量名稱和User對(duì)象的成員變量的名稱是一致的!并且,前面在驗(yàn)證的時(shí)候,我們已經(jīng)把Parameter中帶過來的數(shù)據(jù)封裝到了FormBean對(duì)象中了,所以我們可以使用copyProperties()方法!

使用該方法時(shí),值得注意的是:第一個(gè)參數(shù)是拷貝到哪一個(gè)對(duì)象上(也就是User對(duì)象),第二個(gè)參數(shù)是被拷貝的對(duì)象(也就是formbean對(duì)象),口訣:后拷前....不要搞混了?。。。?!(我就是搞混了,弄了很久...)

處理表單的Servlet完整代碼如下

        //將表單的數(shù)據(jù)封裝到formBean中
        FormBean formBean = WebUtils.request2Bean(request, FormBean.class);

        //驗(yàn)證表單的數(shù)據(jù)是否合法,如果不合法就跳轉(zhuǎn)回去注冊(cè)的頁(yè)面
        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());
            //-----------------------------------


            //調(diào)用service層的注冊(cè)方法,實(shí)現(xiàn)注冊(cè)
            ServiceBussiness serviceBussiness = new UserServiceXML();
            serviceBussiness.register(user1);

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

現(xiàn)在還有問題,如果我填寫信息不合法,提交給服務(wù)器驗(yàn)證以后,服務(wù)器應(yīng)該告訴用戶哪個(gè)信息不合法,而不是直接把跳轉(zhuǎn)回注冊(cè)界面,把所有的信息全部清空,讓用戶重新填寫!

我們應(yīng)該這樣做:當(dāng)發(fā)現(xiàn)用戶輸入的信息不合法時(shí),把錯(cuò)誤的信息記錄下來,等到返回注冊(cè)頁(yè)面,就提示用戶哪里出錯(cuò)了!

在FormBean對(duì)象中添加一個(gè)HashMap集合(因?yàn)榈葧?huì)還要根據(jù)關(guān)鍵字把錯(cuò)誤信息顯示給用戶?。?/strong>

FormBean的全部代碼如下:

    //表單提交過來的數(shù)據(jù)全都是String類型的,birthday也不例外!
    private String username;
    private String password;
    private String password2;
    private String email;
    private String birthday;

    //記錄錯(cuò)誤的信息
    private HashMap error = new HashMap<>();
    
    
    /*用于判斷表單提交過來的數(shù)據(jù)是否合法*/
    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的數(shù)字
        if (this.password == null || this.password.trim().equals("")) {
            error.put("password", "密碼不能為空,并且要是3-8的數(shù)字");
            return false;
        } else {
            if (!this.password.matches("d{3,8}")) {
                error.put("password", "密碼不能為空,并且要是3-8的數(shù)字");
                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;
            }
        }

        //如果上面都沒有執(zhí)行,那么就是合法的了,返回true
        return true;
    }

    //.....各種的setter和getter

在跳轉(zhuǎn)到注冊(cè)頁(yè)面之前,把formbean對(duì)象存到request域中。在注冊(cè)頁(yè)面就可以把錯(cuò)誤的信息取出來(使用EL表達(dá)式)!

處理表單的Servlet的部分代碼

        //驗(yàn)證表單的數(shù)據(jù)是否合法,如果不合法就跳轉(zhuǎn)回去注冊(cè)的頁(yè)面
        if(formBean.validate()==false){

            //在跳轉(zhuǎn)之前,把formbean對(duì)象傳遞給注冊(cè)頁(yè)面
            request.setAttribute("formbean", formBean);
            request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response);
            return;
        }

在注冊(cè)頁(yè)面中,使用EL表達(dá)式把錯(cuò)誤的信息寫出來

測(cè)試:

效果:

做到這里,還是有丟丟的問題,我們不應(yīng)該把用戶輸入的數(shù)據(jù)全部清空的!你想想,如果用戶注冊(cè)需要輸入多個(gè)信息,僅僅一個(gè)出錯(cuò)了,就把全部信息清空,要他重新填寫,這樣是不合理的!

我們?cè)诟鱾€(gè)的輸入項(xiàng)中使用EL表達(dá)式回顯數(shù)據(jù)就行了!

效果:

還沒有完善,細(xì)心的朋友可以發(fā)現(xiàn),上面圖的日期也是錯(cuò)誤的,但是沒一次性標(biāo)記出來給用戶!要改也十分簡(jiǎn)單:在驗(yàn)證的時(shí)候,不要先急著return false 用一個(gè)布爾型變量記住,最后返回布爾型的變量即可

無論注冊(cè)成功還是失敗都需要給用戶一個(gè)友好界面的!

5.2登陸界面

登陸和注冊(cè)是類似的,我們按著注冊(cè)的步驟來寫就對(duì)了!

首先寫一個(gè)提供登陸界面的Servlet


        //直接跳轉(zhuǎn)到登陸界面
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);

寫登陸界面

這是登陸界面

用戶名
密碼

寫處理登陸表單的Servlet

        //獲取提交過來的數(shù)據(jù)
        String username = request.getParameter("username");
        String password = request.getParameter("password");

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

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

效果:

5.3把注冊(cè)和登陸都掛在首頁(yè)上
  

這是首頁(yè)!

登陸 注冊(cè)

總結(jié)

使用JSP+JavaBean開發(fā)一個(gè)簡(jiǎn)單計(jì)算器,是非常容易的,顯示頁(yè)面和請(qǐng)求都是交由JSP來做。沒有什么新的知識(shí)點(diǎn),用一些JSP行為就能完成了。

MVC模式開發(fā)使用Servlet來做處理請(qǐng)求,代碼量略大,但層次清晰

使用BeanUtils開發(fā)組件可以將request請(qǐng)求的參數(shù)封裝到JavaBean對(duì)象中,Date屬性要另外處理

校驗(yàn)的功能也是使用一個(gè)JavaBean來完成,目的就是為了可重用性,職責(zé)分工。同時(shí),我們可以在該JavaBean設(shè)置一個(gè)Map集合來保存錯(cuò)誤的信息,以便在前臺(tái)上展示錯(cuò)誤信息。

如果文章有錯(cuò)的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),可以關(guān)注微信公眾號(hào):Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/68516.html

相關(guān)文章

  • Java3y文章目錄導(dǎo)航

    摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會(huì)更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號(hào):Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡(jiǎn)單 注解就這么簡(jiǎn)單 Druid數(shù)據(jù)庫(kù)連接池...

    KevinYan 評(píng)論0 收藏0
  • JSP面試題都在這里

    摘要:下面是我整理下來的知識(shí)點(diǎn)圖上的知識(shí)點(diǎn)都可以在我其他的文章內(nèi)找到相應(yīng)內(nèi)容。在中,尤其重要的是對(duì)象。 下面是我整理下來的JSP知識(shí)點(diǎn): showImg(https://segmentfault.com/img/remote/1460000013229216?w=4962&h=2653); 圖上的知識(shí)點(diǎn)都可以在我其他的文章內(nèi)找到相應(yīng)內(nèi)容。 JSP常見面試題 jsp靜態(tài)包含和動(dòng)態(tài)包含的區(qū)別 j...

    gaosboy 評(píng)論0 收藏0
  • 最新StarGAN對(duì)抗生成網(wǎng)絡(luò)實(shí)現(xiàn)多領(lǐng)域圖像變換

    摘要:第一列和第六列顯示輸入圖像,其余列是產(chǎn)生的圖像。然而,現(xiàn)有的模型在多域圖像轉(zhuǎn)換任務(wù)中效率低下。該圖表示連接多個(gè)域的拓?fù)鋱D。在訓(xùn)練過程中,隨機(jī)生成目標(biāo)域標(biāo)簽并訓(xùn)練模型,以便靈活地將輸入圖像轉(zhuǎn)換到目標(biāo)域。 圖像到圖像轉(zhuǎn)化的任務(wù)是將一個(gè)給定圖像的特定方面改變到另一個(gè)方面,例如,將一個(gè)人的面部表情從微笑到皺眉改變(見圖1)。自從生成對(duì)抗網(wǎng)絡(luò)(GANs)的引入,這個(gè)任務(wù)經(jīng)歷了很大的發(fā)展,從改變發(fā)色,改...

    fevin 評(píng)論0 收藏0
  • Strict ModeExtended Mode - Javascript語(yǔ)法基礎(chǔ) - Javas

    摘要:之后,在瀏覽器大戰(zhàn)中,成為各方角逐的主要戰(zhàn)場(chǎng)。各大廠商各顯神通,其副作用是各種奇奇怪怪的行為和各式不一的。也就是說,有很多模棱兩可,或是錯(cuò)誤卻被允許的操作,被徹底禁止了。目前支持嚴(yán)格模式的支持范圍從起跳,其他常青瀏覽器也都是支持的。 原文: http://pij.robinqu.me/JavaScript_Core/JavaScript_Basics/Strict_Mode.ht...

    SHERlocked93 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<