人已经在厦工了,寄😭😭😭
这一阶段,基本都是优化,各种优化捏🤗
🤗目录🤗
🤗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 ©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> <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进入新学期
版权归原作者 FLZJ_KL 所有, 如有侵权,请联系我们删除。