书城项目第三阶段
当我们的项目启动之后,访问登录或注册页面,输入需要的信息,点击登录或注册按钮:
注册页面
我们发现,即使输入的用户信息错误,只是跳转回了当前的登录或注册页面,没有任何的提示信息。我们希望当输入的用户信息不正确时,给与用户提示,并且需要回显用户名等信息。
一、页面jsp 动态化
1、在所有html 页面顶行添加page 指令
2、修改所有的文件后缀名为:.jsp
3、需要将所有页面中跳转的页面地址修改为(.jsp)的。使用IDEA 搜索替换.html 为.jsp(快捷键:Ctrl+Shift+R)
==================================================================================================================
项目启动后,访问不同的页面,我们发现:有好多的页面中部分内容都是相同的。如:
为了方便项目后期的管理和维护,需要将这些相同内容抽取到不同的jsp文件中,使用静态包含引用即可。
二、抽取页面中相同的内容
在pages文件夹下新建一个common目录(用来存放具有形同内容的jsp页面):
head.jsp文件(head中的css、jQuery、base标签):
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <% String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/"; %> <!--写base标签,永远固定相对路径跳转的结果--> <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>
footer.jsp页面(每个页面的页脚):
<div id="bottom"> <span> 尚硅谷书城.Copyright ©2015 </span> </div>
login_success_menu.jsp页面(登录成功后的菜单):
<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>
manager.jsp页面(manager管理模块的菜单):
<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>
有了以上的操作,我们需要用到这些代码的地方,只需要使用静态包含的方式引入即可。后期项目如果有改动的地方,只需要修改common下的这些文件即可,不需要每一个页面都去做改动。
====================================================================================================================
三、登录,注册错误提示,及表单回显
登录页面,我们希望得到如下的效果:
1.Servlet 程序端需要添加回显信息到Request 域中
2.jsp 页面,需要输出回显信息
注册页面,我们希望得到如下的效果:
1.Servlet 程序端需要添加回显信息到Request 域中
2.jsp 页面,需要输出回显信息
=============================================================================================================
四、BaseServlet 的抽取
在实际项目开发中,一个模块,一般只使用一个Servlet程序,我们希望将登录和注册的Servlet程序进行合并(后面若有其它的业务,全部合并成一个Servlet即可)。
代码优化一:将LoginServlet和RegistServlet合并成UserServlet。
1.在登录和注册的jsp页面中分别添加隐藏域:
2.在UserServlet程序中通过请求参数action值得不同实现不同的功能分发(记得在web.xml配置UserServlet的访问路径):
public class UserServlet extends HttpServlet { private UserService userService = new UserServiceImpl(); @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); } } protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1、获取请求的参数 String username = req.getParameter("username"); String password = req.getParameter("password"); // 调用 userService.login()登录处理业务 User loginUser = userService.login(new User(null, username, password, null)); // 如果等于null,说明登录 失败! if (loginUser == null) { req.setAttribute("msg", "用户名或密码错误"); req.setAttribute("username", username); // 跳回登录页面 req.getRequestDispatcher("/pages/user/login.jsp").forward(req, resp); } else { // 登录 成功 //跳到成功页面login_success.html req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req, resp); } } 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"); // 2、检查 验证码是否正确 === 写死,要求验证码为:abcde if ("abcde".equalsIgnoreCase(code)) { // 3、检查 用户名是否可用 if (userService.existsUsername(username)) { //讲回显得错误信息保存 req.setAttribute("msg", "用户名已存在"); req.setAttribute("username", username); req.setAttribute("email", email); System.out.println("用户名[" + username + "]已存在!"); // 跳回注册页面 req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp); } else { // 可用 // 调用Sservice保存到数据库 userService.registUser(new User(null, username, password, email)); // // 跳到注册成功页面 regist_success.jsp req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req, resp); } } else { //讲回显得错误信息保存 req.setAttribute("msg", "验证码错误"); req.setAttribute("username", username); req.setAttribute("email", email); System.out.println("验证码[" + code + "]错误"); req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp); } } }
===============================================================================================================
代码优化二:使用反射优化大量else if代码。
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String action = req.getParameter("action"); System.out.println(this.getClass()); try { Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class); method.invoke(this, req, resp); } catch (Exception e) { e.printStackTrace(); } }
=================================================================================================================
代码优化三:抽取BaseServlet类。
在实际开发中,不止是有UserServlet模块,而是有很多的Servlet模块,而且他们的功能都是相似的。
我们将所有的Servlet程序抽取出一个BaseServlet程序,让其他的程序集成这个BaseServlet程序,BaseServlet只需要集成HttpServlet即可。
BaseServlet程序代码:
UserServlet只需集成BaseServlet即可(它也是一个Servlet程序,间接的集成了HttpServlet)。
===================================================================================================================
五、数据的封装和抽取BeanUtils的使用
1.BeanUtils工具类的作用
① BeanUtils 工具类,它可以一次性的把所有请求的参数注入到 JavaBean 中。
② BeanUtils 工具类,经常用于把 Map 中的值注入到 JavaBean 中,或者是对象属性值的拷贝操作。
2.BeanUtils工具类的使用
BeanUtils 它不是 Jdk 的类。而是第三方的工具类。所以需要导包。
3.WebUtils工具类的使用
①创建工具类WebUtils.java。代码如下:
public class WebUtils {
/**
* 将Map中的值注入到bean中
* @param value
* @param bean
* @param <T>
* @return
*/
public static <T> T copyParamToBean(Map value, T bean){
try {
System.out.println("注入之前:" + bean);
/**
* 将所有的请求参数注入到bean对象中
*/
BeanUtils.populate(bean, value);
System.out.println("注入之后:" + bean);
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}
}
②使用WebUtils工具类对请求参数进行封装
===================================================================================================
六、使用EL表达式修改表单回显
1.使用EL表达式替换登录页面中的所有表达式脚本
2.使用EL表达式替换所有注册页面的表达式脚本