【尚硅谷_书城项目三、四阶段】【学习笔记】寒假javaweb学习之旅1.6

人已经在厦工了,寄😭😭😭

这一阶段,基本都是优化,各种优化捏🤗

🤗1、结合之前所学优化

结合之前所学内容,对之前的book项目进行优化

1.1、页面jsp动态化

1、在html页面顶行添加page指令

在这里插入图片描述

2、修改文件后缀名为: .jsp

在这里插入图片描述

3、使用IDEA搜索替换.html.jsp

单个文件里的内容

CTRL + R

在这里插入图片描述

多个文件搜索

CTRL + SHIFT + R

在这里插入图片描述

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

抽取页面中相同的内容 (❌)

静态包含乱杀 (✔)

1.2.1、head 中css、jquery、 base 标签

我们在src/main/webapp/pages/common/下创建一个head.jsp,用来处理代码中重复使用的base标签、css样式、jQuery文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!--写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>

原来的内容就会变成如下的短短几句

<%-- 静态包含 base标签 css样式 jQuery文件 --%>
<%@include file="/pages/common/head.jsp"%>

对比图

在这里插入图片描述

是不是,非常的简洁😍,来,试试看,按照这样,把整个项目都改改吧!!!

1.2.2、每个页面的页脚

在这里插入图片描述
我们还会发现每个页面的底下都有页脚,代码也是完全一样的,所以,我们去src/main/webapp/pages/common/下创建一个footer.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div id="bottom">
		<span>
			尚硅谷书城.Copyright &copy;2015
		</span>
</div>

然后,在使用到这几行代码的地方,替换为静态包含

<%-- 静态包含页脚内容 --%>
<%@include file="/pages/common/footer.jsp"%>

1.2.3、登录成功后的菜单

我们还会发现,下面这几行代码,在整个项目中出现了多次,所以,我们又可以用静态包含😤😤😤

因此,我们在src/main/webapp/pages/common/下创建一个login_success_menu.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<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>

然后在所有重复的地方用,替换

<div id="header">
    <img class="logo_img" alt="" src="static/img/logo.gif" >
    <%-- 静态包含,登入成功的菜单 --%>
    <%@include file="/pages/common/login_success_menu.jsp"%>
</div>

1.2.4、manager 模块的菜单

🤔🤔🤔经过,我们仔细的阅读代码,我们还会发现,在manger模块里,有重复的内容可以用静态包含替换,因此,我们在src/main/webapp/pages/common/下创建一个manager_menu.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div>
    <a href="book_manager.jsp">图书管理</a>
    <a href="order_manager.jsp">订单管理</a>
    <a href="../../index.jsp">返回商城</a>
</div>

然后去替换

<%--  静态包含manager管理模块的菜单 --%>
<%@include file="/pages/common/manager_menu.jsp"%>

1.3、动态的base标签值

我们一般用localhost去访问服务器,那么现在我们换一个ip去访问。因为,我们的base标签写死了,会出现,

在这里插入图片描述

我们ip是192.168.1.6,但是css的url还是loacalhost,因为上面base标签相同,所以jQuery也有这样的问题。

因此,这里我们去src/main/webapp/pages/common/下的head.jsp小改1下

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    // http://localhost:8080/工程路径/
    String basePath = request.getScheme()
        + "://"
        + request.getServerName()
        + ":"
        + request.getServerPort()
        + request.getContextPath()     //request.getContextPath()返回 /工程路径,所以这里不需要加/
        + "/";
%>
<%= basePath %>
<!--写base标签,永远固定相对路径跳转的结果-->
<base href= <%= 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>

在这里插入图片描述

🤗2、表单提交错误回显

图解

在这里插入图片描述

登入部分代码实现

在这里插入图片描述

具体看最后面的几行代码,如果失败,就把信息存到request域中

public class LoginServlet extends HttpServlet {
    private UserService userService = new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        1、获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("接收到用户的账为"+username+"\t"+password);
//        2、调用XxxService. xxx()处理业务
//        userService. login(登录
        User user = userService.login(new User(null, username, password, null));
//                3、根据login()方法返回结果判断登录是否成功
        if(!(user == null)) {
//                成功
//                跳到成功页面login_ success. html
            System.out.println(username + " 登入成功");
            request.getRequestDispatcher("/pages/user/login_success.jsp").forward(request,response);
        }else {
//                失败
//                跳回登录页面
            //把错误的信息(msg),和回显的表单项信息(username),保存到request域中
            request.setAttribute("msg","用户名或密码错误");
            request.setAttribute("username",username);
            System.out.println(username + " 登入失败");
            request.getRequestDispatcher("/pages/user/login.jsp").forward(request,response);
        }
    }
}

后面我们对login.jsp的错误信息部分和用户名(value)部分进行修改

...
<span class="errorMsg">
    <%= request.getAttribute("msg")==null?"请输入用户名和密码":request.getAttribute("msg") %>
</span>
...

<label>用户名称:</label>
<input class="itxt" type="text" placeholder="请输入用户名"
       autocomplete="off" tabindex="1" name="username"
       value="<%= request.getAttribute("username")==null?"":request.getAttribute("username")%>"/>

注册部分代码实现

在这里插入图片描述

主要看后几行的验证码错误,和账号已存在,我们把数据保存到request域中

public class RegistServlet extends HttpServlet {
    private UserService userService = new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        1、 获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        String code = request.getParameter("code");

        System.out.println("读取的数据为" + username +"\t" + password + "\t" + email + "\t" + code);
//        2、检查验证码是否正确      这里我们先写死abcde
        if("abcde".equals(code)) {
//              正确

//        3、检查用户名是否可用
            if(!userService.existsUsername(username)) {
//                可用
//        调用Sservice保存到数据库
                //userService.registUser(new User(null,username,password,email));
//        跳到注册成功末面regist_success.jsp
                request.getRequestDispatcher("/pages/user/regist_success.jsp").forward(request,response);
            }else {
//          不可用
            System.out.println("用户名[ " + username + " ]已存在");
                //把回显信息放到request域中
                request.setAttribute("msg","用户名已存在");
                request.setAttribute("username",username);
                request.setAttribute("email",email);

//          跳回注册页面
            request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
            }
        }else{
//           验证码不正确
            //把回显信息放到request域中
            request.setAttribute("msg","验证码输入有误");
            request.setAttribute("username",username);
            request.setAttribute("email",email);

            System.out.println("验证密码[ "+code+" ]错误");
//        跳回注册页面
            request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
        }
    }
}

注册的页面regist.jsp同样这么处理,我们修改错误信息、用户名、电子邮件

...
<span class="errorMsg">
    <%= request.getAttribute("msg")==null?"" : request.getAttribute("msg")%>
</span>
...
    <label>用户名称:</label>
    <input class="itxt" type="text" placeholder="请输入用户名"
        autocomplete="off" tabindex="1" name="username" id="username"
        value="<%= request.getAttribute("username")==null?"" : request.getAttribute("username")%>"
        />
        ...
    <label>电子邮件:</label>
    <input class="itxt" type="text" placeholder="请输入邮箱地址"
            autocomplete="off" tabindex="1" name="email" id="email"
            value="<%= request.getAttribute("email")==null?"" : request.getAttribute("email")%>"
            />

🤗3、代码优化

3.1、合并注册和登入代码

在这里插入图片描述

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

登入和注册都属于一个模块(用户模块),结合上图,实现合并🤗

代码实现

我们到regist.jsp页面和login.jsp页面,在其表单中添加隐藏域

<input type="hidden" value="login" name="action">		<%--  login.jsp  --%>
<input type="hidden" value="regist" name="action">		<%--  regist.jsp  --%>

同时表单的action属性也要改

<form action="userServlet" method="post">

👇下面更是重量级的结合体UserServlet

public class UserServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //        1、获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("接收到用户的账为"+username+"\t"+password);
        //        2、调用XxxService. xxx()处理业务
        //        userService. login(登录
        User user = userService.login(new User(null, username, password, null));
        //                3、根据login()方法返回结果判断登录是否成功
        if(!(user == null)) {
            //                成功
            //                跳到成功页面login_ success. html
            System.out.println(username + " 登入成功");
            request.getRequestDispatcher("/pages/user/login_success.jsp").forward(request,response);
        }else {
            //                失败
            //                跳回登录页面
            //把错误的信息(msg),和回显的表单项信息(username),保存到request域中
            request.setAttribute("msg","用户名或密码错误");
            request.setAttribute("username",username);
            System.out.println(username + " 登入失败");
            request.getRequestDispatcher("/pages/user/login.jsp").forward(request,response);
        }
    }

    protected void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //        1、 获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        String code = request.getParameter("code");

        System.out.println("读取的数据为" + username +"\t" + password + "\t" + email + "\t" + code);
        //        2、检查验证码是否正确      这里我们先写死abcde
        if("abcde".equals(code)) {
            //              正确

            //        3、检查用户名是否可用
            if(!userService.existsUsername(username)) {
                //                可用
                //        调用Sservice保存到数据库
                //userService.registUser(new User(null,username,password,email));
                //        跳到注册成功末面regist_success.jsp
                request.getRequestDispatcher("/pages/user/regist_success.jsp").forward(request,response);
            }else {
                //          不可用
                System.out.println("用户名[ " + username + " ]已存在");
                //把回显信息放到request域中
                request.setAttribute("msg","用户名已存在");
                request.setAttribute("username",username);
                request.setAttribute("email",email);

                //          跳回注册页面
                request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
            }
        }else{
            //           验证码不正确
            //把回显信息放到request域中
            request.setAttribute("msg","验证码输入有误");
            request.setAttribute("username",username);
            request.setAttribute("email",email);

            System.out.println("验证密码[ "+code+" ]错误");
            //        跳回注册页面
            request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String action = request.getParameter("action");
        if("login".equals(action)) {
            // 登入功能
            login(request,response);
        }else if("regist".equals(action)){
            // 注册功能
            regist(request,response);
        }
    }
}

3.2、使用反射优化大量else if

刚刚,我们用 if 条件判断,对注册和登入功能,进行了区分,但是未来,我们要是往里面加新的功能(添加用户、修改信息、修改密码…),就会非常的麻烦😨 😨 😨

那么我们应该,怎么做呢,其实因为页面传回来的隐藏域的值,和我们要使用的功能的方法同名,我们就可以使用反射来解决🌶😁😁😁

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String action = request.getParameter("action");

    try {
        // 获取action业务鉴别字符串,获取相应的业务 方法反射对象
        Method method = this.getClass().getDeclaredMethod(action,HttpServletRequest.class,HttpServletResponse.class);
        // 调用目标业务 方法
        method.invoke(this,request,response);

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

}

下面,我们启动服务器,进入login.jsp(登入界面)进行debug,我们可以看👀到,已经反射出了我们的注册方法

在这里插入图片描述

3.3 BaseServlet优化

在这里插入图片描述

刚刚,我们优化了用户模块的代码,那么,我们一想🤔🤔🤔🤔,嗨呀🤗,其他模块,也是这样的优化方式,那我们可以写一个BaseServlet,来减少重复的代码

public abstract class BaseServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String action = request.getParameter("action");

        try {
            // 获取action业务鉴别字符串,获取相应的业务 方法反射对象
            Method method = this.getClass().getDeclaredMethod(action,HttpServletRequest.class,HttpServletResponse.class);
            // 调用目标业务 方法
            method.invoke(this,request,response);

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

原来的UserServlet不继承HttpServlet,只需要继承BaseServlet就行了😍😍😍

public class UserServlet extends BaseServlet {...}

🤗4、BeanUtils工具类

4.1、BeanUtils简单介绍

我们会发现,自己new一个 bean再setXxx()太累了,所以我们要解放自己我😤

BeanUtils工具类,它可以一次性的把所有请求的参数注入到JavaBean中😍
BeanUtils它不是Jdk的类。而是第三方的工具类。所以需要导包😍

导入需要的jar包:

commons-beanutils-1.8.0.jar
commons-logging 1.1.1.jar

在这里插入图片描述

4.2、使用BeanUtils类方法实现注入

try {
    User user = new User();
    System.out.println("注入之前: " + user);
    // 把所有请求的参数都注入到user对象中
    BeanUtils.populate(user,request.getParameterMap());
    System.out.println("注入之后: " + user);
} catch (Exception e) {
    e.printStackTrace();
}

在这里插入图片描述

4.3、优化BeanUtils

那么,每个方法都这么写就很麻烦了,所以我们可以写一个工具类,要用的时候,直接一行调用😁,所以我们写一个WebUtils

public class WebUtils {
    public static void copyParamToBean(HttpServletRequest request, Object bean){
        try {
            User user = new User();
            System.out.println("注入之前: " + bean);
            // 把所有请求的参数都注入到user对象中
            BeanUtils.populate(bean,request.getParameterMap());
            System.out.println("注入之后: " + bean);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

但是这么写,耦合性还是太高了,我们把copyParamToBean()方法的参数HttpServletRequest request 改成 Map map ,为什么这么做捏?🤗,原来是,javaEE的三层结构 : Dao 层、Service 层、Web 层,如果函数的参数写成HttpServletRequest request,Dao层和Service层就用不了了,但时Map,这三层都能用。

还有,这里写成泛型,会使得代码只写一行,不用强转成User(类),更为整洁,所以这样更好😍

User user = WebUtils.copyParamToBean(request.getParameterMap(),new User());	//一行调用
public class WebUtils {
    public static <T> T copyParamToBean(Map map, T bean){
        try {
            User user = new User();
            System.out.println("注入之前: " + bean);
            // 把所有请求的参数都注入到user对象中
            BeanUtils.populate(bean,map);
            System.out.println("注入之后: " + bean);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }
}

4.4、BeanUtils根据SetXxx() 方法实现注入

我们找到User类,把其中的SetPassword()去掉,这时,我们可以看到,密码没有值注入进去

在这里插入图片描述


下面是尚硅谷书城项目第四阶段

🤗5、用EL表达式修改表单回显

之前我们写的JSP做回显,不太好看,所以这里我们用EL表达式优化

登入页面

<%= request.getAttribute("msg")==null?"请输入用户名和密码":request.getAttribute("msg") %>

可以改成

${empty requestScope.msg ? "请输入用户名和密码" : requestScope.msg}

username也这样改

value="<%= request.getAttribute("username")==null?"":request.getAttribute("username")%>"
<%-- 改为 --%>
value="${requestScope.username}"

之前的EL表达式学习笔记里,有说过,EL表达式没有找到对应的值,就会输出空串,所以我们可以直接这样写。

注册页面

<span class="errorMsg">
    <%--									<%= request.getAttribute("msg")==null?"" : request.getAttribute("msg")%>--%>
    ${requestScope.msg}
</span>
<label>用户名称:</label>
<input class="itxt" type="text" placeholder="请输入用户名"
       autocomplete="off" tabindex="1" name="username" id="username"
       value="${requestScope.username}"
       />

<label>电子邮件:</label>
<input class="itxt" type="text" placeholder="请输入邮箱地址"
       autocomplete="off" tabindex="1" name="email" id="email"
       value="${requestScope.email}"
       />

新的学期,你准备好了吗?😁,扣1进入新学期

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值