如果用户在登入画面成功登入,则在session创建用户对象及其购物车对象。
若失败则返回登入页面,提示重新登入。
新建LoginSvl
@WebServlet("/LoginSvl")public class LoginSvl extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/main/login.jsp").forward(request, response); }}
从首页的登入按钮触发以下连结,呼叫LoginSvl的doGet()方法,转发到login.jsp
localhost:8080/BookShop/LoginSvl
如果用户在login.jsp输入帐号密码并送出,则会触发doPost()方法。
编辑doPost()方法
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uname = request.getParameter("uname"); String pwd = request.getParameter("pwd"); if(uname != null && pwd != null && !uname.equals("") && !pwd.equals("")) { UserBiz biz = new UserBiz(); try { TUser user = biz.login(uname,pwd); if(user != null) { //登入成功 request.getSession().setAttribute("user", user); Map<String,Integer> shopCar = new HashMap<String,Integer>(); request.getSession().setAttribute("shopCar", shopCar); request.getRequestDispatcher("/MainSvl").forward(request, response); }else { //登入失败 request.setAttribute("msg", "用户名或密码错误"); request.getRequestDispatcher("/WEB-INF/main/login.jsp").forward(request, response); } }catch(InputNullException e) { request.setAttribute("msg", e.getMessage()); request.getRequestDispatcher("/WEB-INF/main/login.jsp").forward(request, response); }catch(Exception e) { Log.logger.error(e.getMessage(), e); request.setAttribute("msg", e.getMessage()); request.getRequestDispatcher("/WEB-INF/main/login.jsp").forward(request, response); } }else { request.setAttribute("msg", "用户名或密码不能为空"); request.getRequestDispatcher("/WEB-INF/main/login.jsp").forward(request, response); } }
新增UserBiz
public TUser login(String uname, String pwd) throws Exception{ TUser user = null; if(uname == null || pwd == null || uname.equals("") || pwd.equals("")) { throw new InputNullException("用户名或密码不能为空"); } IUserDao dao = new UserDaoMysql(); try { user = dao.login(uname,pwd); }finally{ dao.closeConnection(); } return user; }}
新增UserDaoMysql
public class UserDaoMysql extends BaseDao { public TUser login(String uname,String pwd) throws Exception{ TUser user = null; String sql = "select * from tuser where name = ? and pwd = ?"; this.openConnection(); PreparedStatement ps = this.connection.prepareStatement(sql); ps.setString(1, uname); ps.setString(2, pwd); ResultSet rs = ps.executeQuery(); if(rs != null) { while(rs.next()) { user = new TUser(); user.setUname(uname); user.setPwd(pwd); user.setAccount(rs.getDouble("account")); user.setRole(Integer.parseInt(rs.getString("role"))); break; } } rs.close(); ps.close(); return user; }}
用户登出
当用户点击登出钮,清空session并重定向至首页。
新增LogoutSvl
需为已登入用户才能登出,因此连结网址前缀需为/user/*,让过滤器进行检查。
@WebServlet("/user/LogoutSvl")public class LogoutSvl extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getSession().invalidate(); //request.getRequestDispatcher("/WEB-INF/main/main.jsp").forward(request, response); String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; response.sendRedirect(basePath + "MainSvl"); }}
记忆重点
使用request.getSession().invalidate();让session失效。使用response.sendRedirect(url);进行重定向。不使用转发是为了让url列更新。进行重定向需先準备好绝对路径。用户注册
在用户注册页面,需校验用户名是否重複
使用AJAX搭配UnameCheckSvl进行校验
新增regist.jsp页面
使用input标籤的onkeyup方法触发校验函式。
<table> <tr> <td width="107" height="36">用户名:</td> <td width="524"> <input type="text" id="uname" name="uname" maxlength="16" onkeyup="unameValid()"> <span id="unameAlert" style="color:red;font-size:8px"></span> </td> </tr> <tr> <td>密码</td> <td><input type="password" name="pwd"></td> </tr> <tr> <td>密码确认</td> <td><input type="password" name="pwd2"></td> </tr> <tr> <td><input type="submit" value="送出"></td> <td><a href="<%=basePath%>MainSvl>">返回</a></td> </tr></table>
编写校验函式
<script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.4.min.js"></script><script type="text/javascript"> function unameValid(){ var uname = $('#uname').val(); if(uname != ""){ var destUrl = "<%=basePath%>UnameCheckSvl?uname=" + uname; $.ajax({ type:"GET", url:destUrl, dataType:"text", timeout:3000, success:function(msg){ if(msg == 0){ $('#unameAlert').html('用户名可用'); }else if(msg == 1){ $('#unameAlert').html('用户名重複'); }else if(msg == 2){ $('#unameAlert').html('系统异常'); }else{} }, error:function(){ alert("连线逾时"); } }); } }</script>
记忆重点
使用$('#uname').val();取得要校验的资料事先準备好目标Servlet的url,并把要校验的资料也加进去。使用jquery的 $.ajax({});招唤AJAX。新增UnameCheckSvl
@WebServlet("/UnameCheckSvl")public class UnameCheckSvl extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ String uname = request.getParameter("uname"); UserBiz biz = new UserBiz(); PrintWriter out = response.getWriter(); try { boolean bRet = biz.isHaveUserName(uname); if(bRet) { out.print("1"); //用户名重複 }else { out.print("2"); //用户名可用 } }catch(Exception e) { out.print("-1"); } out.flush(); out.close(); }}
校验后使用response.getWriter();写出结果。
在UserBiz内新增isHaveUserName(String uname)
public boolean isHaveUserName(String uname) throws Exception{ if(uname == null || uname.trim().equals("")) { throw new Exception("用户名不能为空"); } IUserDao dao = new UserDaoMysql(); try { return dao.isHaveUserName(uname); }finally{ dao.closeConnection(); } }
在UserDaoMysql内新增isHaveUserName(String uname)
public boolean isHaveUserName(String uname) throws Exception{ boolean bFind = false; String sql = "select uname from tuser where uname = ?"; this.openConnection(); PreparedStatement ps = this.connection.prepareStatement(sql); ps.setString(1, uname); ResultSet rs = ps.executeQuery(); while(rs.next()) { bFind = true; break; } rs.close(); ps.close(); return bFind; }
记忆重点
ResultSet在这边没有进行null判定。查了一下发现即便返回0件资料,也可以用while(rs.next())来确认,不会报空指针错误。进行null判定是当有处理要放在迴圈外时使用,例如new ArrayList<>()之类的。注册
校验完成后即可进入注册程序
修改regist.jsp
<form action="<%=basePath%>RegistSvl" id="myform" onsubmit="return checkUserInfo()" method="post"> <table border="0" cellpadding="0" cellspacing="0" align="center"> <tr><td height="100"></td></tr> <tr> <td width="107" height="36">用户名:</td> <td width="524"><input type="text" id="uname" name="uname" maxlength="16" onkeyup="unameValid()"> <span id="unameAlert" style="color: red; font-size: 8px"></span></td> </tr> <tr> <td width="107" height="36">密码:</td> <td width="524"><input type="password" id="pwd" name="pwd"></td> </tr> <tr> <td width="107" height="36">确认密码:</td> <td width="524"><input type="password" id="pwd2" name="pwd2"></td> </tr> <tr> <td colspan="2"> <input type="submit" value="送出"> <a href="<%=basePath%>MainSvl>">返回</a> </td> </tr> <tr> <td colspan="2"> <span style="color:red;font-size:8px">${msg }</span> </td> </tr> </table> </form>
记忆重点
使用标籤来建立HTML表单表单可指定目标url表单可使用onsubmit()在送出前进行资料检查使用来设定表单格式虽然不使用和也可以送出资料,不过正式的格式还是应该套用这些标籤。
新增js脚本checkUserInfo()
function checkUserInfo(){ var uname = $(#'uname').val(); var pwd = $(#'pwd').val(); var pwd2 = $(#'pwd2').val(); if(uname == ""){ alert("用户名不能为空!"); return false; } if(pwd == ""){ alert("密码不能为空!"); return false; } if(pwd2 != pwd){ alert("密码不一致!"); return false; } }
新建RegistSvl
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/main/regist.jsp").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uname = request.getParameter("uname"); String pwd = request.getParameter("pwd"); UserBiz biz = new UserBiz(); TUser user = new TUser(); user.setUname(uname); user.setPwd(pwd); user.setRole(IRole.CUSER); try { biz.addUser(user); request.setAttribute("msg", "注册成功,请重新登入"); request.getRequestDispatcher("/WEB-INF/main/login.jsp").forward(request, response); }catch(java.sql.SQLIntegrityConstraintViolationException e){ request.setAttribute("msg", "用户名冲突,请重新输入"); request.getRequestDispatcher("/WEB-INF/main/regist.jsp").forward(request, response); }catch(Exception e) { request.setAttribute("msg", "系统忙碌中,请稍后再试"); request.getRequestDispatcher("/WEB-INF/error.jsp").forward(request, response); } }
记忆重点,Servlet负责:
取得表单参数叫服务层出来干活依据处理结果将用户导向不同网页修改UserBiz,新增addUser()
public void addUser(TUser user) throws Exception{ IUser dao = new UserDaoMysql(); try { dao.addUser(user); }finally { dao.closeConnection(); } }
记忆重点,Biz负责:
叫DAO层出来干活活做完关connection出问题使用throws Exception回报给Servlet修改UserDaoMysql,新增addUser()
public void addUser(TUser user) throws Exception{ String sql = "insert into tuser values(?,?,?,?)"; this.openConnection(); PreparedStatement ps = this.connection.prepareStatement(sql); ps.setString(1, user.getUname()); ps.setString(2, user.getPwd()); ps.setDouble(3, user.getAccount()); ps.setInt(4, IRole.CUSER); ps.executeUpdate(); ps.close(); }