JavaWeb开发项目 电子书城项目(二) 优化电子书城项目代码

前面我们已经对电子书城项目中用户模块进行实现,但是在代码上可以进行再一部优化,可以使代码更具有维护性和扩展性。

1.页面进行jsp动态化

对前端代码中的html代码进行jsp动态化处理,处理的步骤如下:

  • 1.在html页面中第一行添加page指令。
  • 2.将html文件后缀名修改为.jsp。
  • 3.在编译器IDEA中进行搜索替换。(IDEA中快捷键:Ctrl+Shift+R可以实现搜索替换功能)。

在IDEA中执行搜索替换的操作如下图所示:
在这里插入图片描述

将html文件修改为jsp文件的效果如下:
在这里插入图片描述


2.当登录或者注册失败时,提供错误提示进行表单回显

当用户登录失败后,Servlet程序段需要添加回显信息到Request域中,才能进行对应的表单回显。

public class LoginServlet extends HttpServlet {
    private UserService userService=new UserServiceImpl();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        //2.调用service层进行登录
        if (userService.login(new User(null,username,password,null))==null) {
            //返回null表示登录失败
            //把错误信息,和回显表单项信息,保存在Request域中
            req.setAttribute("msg","用户名或者密码错误");
            req.setAttribute("username",username);
            //跳转回登录界面
            req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);
        }else{
            //登陆成功
            //跳转到登录成功界面
            req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp);
        }

    }


}

jsp页面,需要对回显信息进行输出

<span class="errorMsg">
//对回显信息进行输出							
<%=request.getAttribute("msg")==null?"请输入用户名或者密码":request.getAttribute("msg")%>
								</span>
							</div>
							<div class="form">
								<form action="userServlet" method="post">
									<input type="hidden" name="action" value="login" />
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名"
										   autocomplete="off" tabindex="1" name="username"
		//对回显信息进行显示								   
										   value=<%=request.getAttribute("username")==null?"":request.getAttribute("username")%> >

当登录失败时,提供错误提示进行表单回显的效果:
在这里插入图片描述


3.BaseServlet的抽取

在项目开发中,一个模块一般只使用一个Servlet程序。

3.1 将LoginServlet和Register程序合并为UserServlet

在这里插入图片描述
在login.jsp页面和regist.jsp页面中增加hidden标签,分别表示登录和注册功能。然后将LoginServlet和RegistServet合并成一个UserServlet程序。

public class UserServlet extends HttpServlet {
      private UserService userService = new UserServiceImpl();
			/**
			* 处理登录的功能
			* @param req
			* @param resp
			* @throws ServletException
			* @throws IOException
			*/
	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) {
		// 把错误信息,和回显的表单项信息,保存到 Request 域中
		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);
		}
		}
		/**
		* 处理注册的功能
		* @param req
		* @param resp
		* @throws ServletException
		* @throws IOException
		*/
		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)) {
		System.out.println("用户名[" + username + "]已存在!");
		// 把回显信息,保存到 Request 域中
		req.setAttribute("msg", "用户名已存在!!");
		req.setAttribute("username", username);
		req.setAttribute("email", email);
		//
		跳回注册页面
		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 {
		// 把回显信息,保存到 Request 域中
		req.setAttribute("msg", "验证码错误!!");
		req.setAttribute("username", username);
		req.setAttribute("email", email);
		System.out.println("验证码[" + code + "]错误");
		req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp);
		}
		}
		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添加隐藏域和修改请求地址。

<form action="userServlet" method="post">		
  <input type="hidden" name="action" value="login" />

在regist.jsp添加隐藏域和修改请求地址。

<form action="userServlet" method="post">		
	<input type="hidden" name="action" value="regist"/>

3.2 使用反射来优化大量的else if代码

在实际中,用户模块除过注册登录功能外,还具有很多功能。代码中具有很多else if方法,随着方法的增多,代码的维护性和可复用性不高。出现这种情况,我们可以使用反射来优化大量else if代码。

 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        //获取action参数值
        String action = req.getParameter("action");
        try {
            //通过反射获取action对应的业务方法
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            //通过反射调用业务方法
            method.invoke(this,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

3.3 抽取BaseServlet程序

在这里插入图片描述

public abstract class BaseServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        //获取action参数值
        String action = req.getParameter("action");
        try {
            //通过反射获取action对应的业务方法
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            //通过反射调用业务方法
            method.invoke(this,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
}


4.BeanUtils的使用

BeanUtils工具类,它可以一次性把所有的请求的参数注入到JavaBean中。BeanUtils工具类,经常用于把Map中的值注入到JavaBean中,或者是对象属性值的拷贝操作。

BeanUtils 它不是 JDK 的类,而是第三方的工具类。导入需要的 jar 包:
commons-beanutils-1.8.0.jar,commons-logging-1.1.1.jar。

编写WebUtils工具类:

public class WebUtils {
    /**
     * 把Map中的值注入到对应的JavaBean属性中。
     * @param value
     * @param bean
     */
    public static <T> T copyParamToBean( Map value , T bean ){
        try {
            System.out.println("注入之前:" + bean);
            /**
             * 把所有请求的参数都注入到user对象中
             */
            BeanUtils.populate(bean, value);
            System.out.println("注入之后:" + bean);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }
}

版权声明:本文为qq_41537102原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。