【左京淳的JAVA WEB学习笔记】第十二章 用户管理

如果用户在登入画面成功登入,则在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">          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;          <input type="submit" value="送出">&nbsp;          <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();  }

记忆重点,Dao负责:

準备好sql文openConnection()prepareStatement(sql)依照资料型态使用setString、setInt等方法将资料写入prepareStatement物件executeUpdate(),记得查询(executeQuery)与编辑资料(executeUpdate)是不同指令。close()

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章