zoukankan      html  css  js  c++  java
  • 【JavaWeb 实际项目 03】

    第一阶段:主要是通过jQuery对注册页面的用户名+密码+邮箱等作出的一些限制

    第二阶段: 实现用户注册和登录

    第三阶段:主要是优化注册和登录,给用户一些友好的信息提示

    步骤:

    1、页面jsp动态化

    • 在html页面顶行添加page指令
    • 修改文件后缀名为:.jsp
    • 使用IDEA搜索替换.html为.jsp

    2、抽取页面中相同的内容

    1)登录成功后的菜单

    <div>
        <span>欢迎<span class="um_span"></span>光临尘封网书城</span>
        <a href="order/order.jsp">我的订单</a>
        <a href="index.jsp">注销</a>&nbsp;&nbsp;
        <a href="index.jsp">返回</a>
    </div>

    2)head中的css、jquery、base标签

    <base href="http://localhost:8080/book/">
    <link type="text/css" rel="stylesheet" href="static/css/style.css" >
    <script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>

    发现上面的ip地址是写死了,这样代码由本地部署到服务器上就很容易报错,所以我们需要动态获取base的地址

    <%--
      Created by IntelliJ IDEA.
      User: wufq
      Date: 2021/7/1
      Time: 15:16
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%
        //EL表达式pageContext对象的使用。
        //动态获取地址
        String basepATH = request.getScheme() //获取服务器请求的协议
                +"://"
                +request.getServerName()
                +":"
                +request.getServerPort()
                +request.getContextPath() //获取当前工程路径
                +"/";
    %>
    <%--<%=basepATH%>--%>
    <base href="<%=basepATH%>">
    <link type="text/css" rel="stylesheet" href="static/css/style.css" >
    <script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>

    3)每个页面的页脚

    <div id="bottom">
                <span>
                    尘封网.Copyright &copy;2013
                </span>
    </div>

    4)manager模块的菜单

    <div>
        <a href="book_manager.jsp">图书管理</a>
        <a href="order_manager.jsp">订单管理</a>
        <a href="index.jsp">返回商城</a>
    </div>

     以上内容都抽取以后,在对应的文件内引入jsp的静态包含

    如:
    
    <%--静态包含登录成功后的菜单--%>
    <%@include file="/pages/common/login_seccess.jsp"%>

    3、登录、注册错误提示以及表单里面的内容回显

    当我们账号或者密码输入错误以后,希望界面弹出提示信息并且用户名的文本框显示之前输入的用户名

    ===登录错误提示和回显信息===

    1)首先在LoginServlet类内把错误信息和用户名保存到域中

    if(loginUser ==null){
    //            System.out.println("登录失败!");
                //把错误信息和回显的用户名保存到request域中
                req.setAttribute("msg","用户名或密码错误!");
                req.setAttribute("username",username);
    
                req.getRequestDispatcher("/pages/user/login.jsp").forward(req, resp);
            }else {
                System.out.println("欢迎["+username+"]登录尘封网");
                req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req, resp);
            }

    2)修改login.jsp页面,显示回显信息

    <div class="msg_cont">
        <b></b>
        <span class="errorMsg">
    <%
         String msg =(String)request.getAttribute("msg");
    %>
    <%=msg==null?"请输入用户名和密码":msg%>
        </span>
    </div>
    
    <form action="loginServlet" method="post">
        <label>用户名称:</label>
    <%
    String user =(String)request.getAttribute("username");
    %>
    <input class="itxt" type="text" placeholder="请输入用户名" autocomplete="off" tabindex="1" name="username"
     value="<%=user==null?"":user%>"
    />

    ===注册错误提示和回显信息和登录一样===

    4、BaseServlet的抽取

    在实际项目开发中,一个模块,一般只使用一个Servlet程序

    代码优化一:代码优化:合并LoginServlet和RegistServlet程序为UserServlet

    为什么合并?

    查看login.jsp和regist.jsp文件发现?两种发送给服务端的方式都是一样的

    <form action="LoginServlet" method="post">
        <input type="hidden" name="action" value="login">
    
    <form action="RegistServlet" method="post">
         <input type="hidden" name="action" value="regist">

    服务端的LoginServlet和RegistServlet里面的方法是doPost方法,主要也是通过获取name=action然后分别判断到底是login还是regist

     String action = req.getParameter("action");
    
            if("login".equals(action)){
                login(req, resp);//处理登录业务
            }else if("regist".equals(action)){
                regist(req, resp); //处理注册业务
            }

    ---->  UserServlet代码

    package com.wufq.web;
    
    import com.wufq.pojo.User;
    import com.wufq.service.UserService;
    import com.wufq.service.impl.UserServiceImpl;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/7/1 19:52
     */
    public class UserServlet  extends BaseServlet{
    
        private UserService userService = new UserServiceImpl();
    
        private void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
            //        1、获取请求的参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            String email = req.getParameter("email");
            String code = req.getParameter("code");
    
    //        2、检查验证码是否正确  ===  写死,要求验证码为:abcde  (一般验证码由服务器生成,这个先写死)
            if("abcde".equalsIgnoreCase(code)){
    //            3、验证码正确,在继续检查用户名是否可用
                if(userService.existesUserName(username)){
                    //用户名存在,跳回注册页面
    //                System.out.println("用户名["+username+"]已存在");
                    req.setAttribute("msg","用户名已存在");
                    req.setAttribute("username",username);
                    req.setAttribute("email",email);
                    req.getRequestDispatcher("/pages/user/regist.jsp").forward(req,resp);
                }else {
                    //用户名不存在,调用UserService保存在数据库,并且页面跳转到注册成功页面
                    userService.registUser(new User(null,username,password,email));
                    req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req,resp);
                }
            }else{
    //            4、不正确,页面跳转仍然跳转到注册页面
                System.out.println("验证码["+code+"]错误");
                req.getRequestDispatcher("pages/user/regist.jsp").forward(req,resp);
            }
        }
    
        private void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
            //        1、获取请求的参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
    
    //        2、调用userService.login()登录处理业务
            User loginUser = userService.login(new User(null, username, password, null));
    
            if(loginUser ==null){
    //            System.out.println("登录失败!");
                //把错误信息和回显的用户名保存到request域中
                req.setAttribute("msg","用户名或密码错误!");
                req.setAttribute("username",username);
    
                req.getRequestDispatcher("/pages/user/login.jsp").forward(req, resp);
            }else {
                System.out.println("欢迎["+username+"]登录尘封网");
                req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req, resp);
            }
    
    @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String action = req.getParameter("action");
    
            if("login".equals(action)){
                login(req, resp);
            }else if("regist".equals(action)){
                regist(req, resp);
            }
    
        }
    
        }
        
    }

    ---->修改Login.jsp、regist.jsp内请求方式

    代码优化二:优化UserServlet中doPost方法

    String action = req.getParameter("action");
    if("login".equals(action)){
                login(req, resp);
            }else if("regist".equals(action)){
                regist(req, resp);
            }

    当前来讲只有登录和注册,如果后面还有其他的业务,比如:添加用户,修改用户信息,修改密码等,那么每次都增加一个else if,代码会很繁琐,所以需要优化

    ---观察发现,不管是login还是regist判断都是根据前端的action来判断并执行对应的方法(login),所以可以用反射来替代if这种判断来获取起方法名以及执行

    public abstract class BaseServlet  extends HttpServlet{
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String action = req.getParameter("action");
    
            try {
    //          //通过反射获取login,regist方法
                Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
                //调用方法
                method.invoke(this,req, resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }

    解释:

    this.getClass() 是获取类对象,this指的是当前对象,这里特殊,一般用的是BaseServlet.getClass()来获取

    .getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class); 获取方法名对象,action是方法名,后面两个是参数

    method.invoke(this,req, resp);  这是执行方法,this是对象,后面两个是方法的参数

    这里面还缺少一个对象的声明:this.getClass().newInstance();

    ----上面那部分代码也是公共的,所以封装成一个公用的类,设置成abstract,后面的UserServlet继承即可

    5、数据的封装和抽取BeanUtils的使用

     为什么要封装BeanUtils工具类?-->不管是登录还是注册,都需要获取请求参数,然后封装成User对象,这两个功能参数还少,如果是一个参数与特别多的功能,那这部分的工作就很繁琐并且代码也臃肿,所以就用到了BeanUtils工具类封装

      String username = req.getParameter("username");
      String password = req.getParameter("password");
    
     User loginUser = userService.login(new User(null, username, password, null));

    BeanUtils工具类的其中一个作用:它可以一次性的把所有的请求参数注入到javaBean中

    BeanUtils他不是jdk的类,而是第三方的工具类,所以需要需要导包

    1)需要导入的jar包 (必须导两个,少导一个的话会报错)

      commons-beanutils-1.8.0.jar

      commons-logging-1.1.1.jar

    2)演示如何使用

    protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
            //        1、获取请求的参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            String email = req.getParameter("email");
            String code = req.getParameter("code");
    
            try {
                User user = new User();
                System.out.println("注入之前"+user); //User{id=null, username='null', password='null', email='null'}
                /*
                * 把所有请求的参数注入到user对象中
                */
                BeanUtils.populate(user,req.getParameterMap());
                System.out.println("注入之后"+user); //User{id=null, username='test888', password='111111', email='test888@qq.com'}
            } catch (Exception e) {
                e.printStackTrace();
            } 

    上面的这一句代码就已经把参数注入到user对象里面了

    3)封装成webUtils工具类

    package com.wufq.utils;
    
    import org.apache.commons.beanutils.BeanUtils;
    
    import java.util.Map;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/7/2 16:06
     */
    public class WebUtils {
    
        /*
        * 把Map中的值注入到javabean中
         * @param: req
         * @param: bean
        * @Return: void
        */
    //    public static void copyParamToBean(HttpServletRequest req,Object bean){
    //    public static void copyParamToBean(Map  value, Object bean){
        public static <T> T copyParamToBean(Map  value, T bean){
    
            try {
                //把所有请求的参数都注入到User对象中
                /*
                * 这行代码的是关键,意思是req获取请求的参数已map的key、value形式存储然后传递给bean对象
                * 但是如果HttpServletRequest req这种方式写的话,对web层耦合度高,但是对service层和dao层就不太适合
                * 所以既然req.getParameterMap()是一个map集合,那么直接就可以把HttpServletRequest req写成Map value
                */
    //            BeanUtils.populate(bean,req.getParameterMap());
                BeanUtils.populate(bean, value);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return bean;
        }
    }

    4)修改UserServlet内注册成功、登录成功需要传入的user

    protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
            //        1、获取请求的参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            String email = req.getParameter("email");
            String code = req.getParameter("code");
    
            //调用WebUtils把请求注入到user对象中
            User user = copyParamToBean(req.getParameterMap(),new User());
            ....
            userService.registUser(user);//把user对象传入到registUser中   
    
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
            //        1、获取请求的参数
            String username = req.getParameter("username");
            String password = req.getParameter("password");
    
            //调用WebUtils把请求注入到user对象中
            User user = copyParamToBean(req.getParameterMap(),new User());
    //        2、调用userService.login()登录处理业务
            //User loginUser = userService.login(new User(null, username, password, null));
            User loginUser = userService.login(user);
            

     第四阶段 使用EL表达式修改表单回显

  • 相关阅读:
    memcached stats 命令
    sql server 游标语法
    iis 备份
    在Win7下使用超级任务栏时,将文件夹锁定在超级任务栏打开的默认都是计算机
    微点破解90天
    win7 设置 开始菜单 程序 为经典模式
    设置 ASP.NET 存储当前应用程序的临时文件(生成的源、编译了的程序集等)的目录的物理路径。
    Java六大必须理解的问题
    Windows不能在本地计算机启动OracleDBConsoleorcl
    更改phpMyAdmin的密码
  • 原文地址:https://www.cnblogs.com/frankruby/p/14959030.html
Copyright © 2011-2022 走看看