【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表达式修改表单回显

原文地址:https://www.cnblogs.com/frankruby/p/14959030.html