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;
}
}