为了账号安全,请及时绑定邮箱和手机立即绑定

Web开发模式【Mode I 和Mode II的介绍、应用案例】(2)

标签:
Java
  • 接下来我们测试一下吧!将所有的信息都按照规定的输入!

  • 没有问题!已经将记录写到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集合来保存错误的信息,以便在前台上展示错误信息。
点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消