0


【尚硅谷_书城项目三、四阶段】【学习笔记】寒假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标签,永远固定相对路径跳转的结果--><basehref="http://localhost:8080/book/"><linktype="text/css"rel="stylesheet"href="static/css/style.css"><scripttype="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>

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

<divid="header"><imgclass="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域中

publicclassLoginServletextendsHttpServlet{privateUserService userService =newUserServiceImpl();@OverrideprotectedvoiddoPost(HttpServletRequest request,HttpServletResponse response)throwsServletException,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(newUser(null, username, password,null));//                3、根据login()方法返回结果判断登录是否成功if(!(user ==null)){//                成功//                跳到成功页面login_ success. htmlSystem.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域中

publicclassRegistServletextendsHttpServlet{privateUserService userService =newUserServiceImpl();@OverrideprotectedvoiddoPost(HttpServletRequest request,HttpServletResponse response)throwsServletException,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、检查验证码是否正确      这里我们先写死abcdeif("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

publicclassUserServletextendsHttpServlet{privateUserService userService =newUserServiceImpl();protectedvoidlogin(HttpServletRequest request,HttpServletResponse response)throwsServletException,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(newUser(null, username, password,null));//                3、根据login()方法返回结果判断登录是否成功if(!(user ==null)){//                成功//                跳到成功页面login_ success. htmlSystem.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);}}protectedvoidregist(HttpServletRequest request,HttpServletResponse response)throwsServletException,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、检查验证码是否正确      这里我们先写死abcdeif("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);}}@OverrideprotectedvoiddoPost(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{String action = request.getParameter("action");if("login".equals(action)){// 登入功能login(request,response);}elseif("regist".equals(action)){// 注册功能regist(request,response);}}}

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

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

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

@OverrideprotectedvoiddoPost(HttpServletRequest request,HttpServletResponse response)throwsServletException,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,来减少重复的代码

publicabstractclassBaseServletextendsHttpServlet{@OverrideprotectedvoiddoPost(HttpServletRequest request,HttpServletResponse response)throwsServletException,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就行了😍😍😍

publicclassUserServletextendsBaseServlet{...}

🤗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 =newUser();System.out.println("注入之前: "+ user);// 把所有请求的参数都注入到user对象中BeanUtils.populate(user,request.getParameterMap());System.out.println("注入之后: "+ user);}catch(Exception e){
    e.printStackTrace();}

在这里插入图片描述

4.3、优化BeanUtils

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

publicclassWebUtils{publicstaticvoidcopyParamToBean(HttpServletRequest request,Object bean){try{User user =newUser();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(),newUser());//一行调用
publicclassWebUtils{publicstatic<T>TcopyParamToBean(Map map,T bean){try{User user =newUser();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进入新学期

标签: tomcat java-ee servlet

本文转载自: https://blog.csdn.net/flzjcsg3/article/details/123159557
版权归原作者 FLZJ_KL 所有, 如有侵权,请联系我们删除。

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

还没有评论