JavaSE02_Day05(下)-WebServer项目(十一、十二):完善WebServer登录业务、重构响应页面逻辑代码

1.1 版本十一:登录业务

  用户打开登录页面输入对应的登录信息后,点击登录按钮,服务端在接收这些数据以后,与user.txt文件中的已经注册过的用户信息做比对,如果匹配,则服务端响应一个登录成功页面,否则响应登录失败页面。

实现步骤:

  1.在webapps/myweb目录下创建三个页面login.html 需要设置form表单中的action="./login", method="get" 以及两个输入框(用户名和密码)

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>登录页面</title>
 </head>
 <body>
     <center>
  <h1>用户登录页面</h1>
  <form action="login" method="get">
  <table border="1">
  <tr>
  <td>用户名:</td>
  <td><input type="text" name="username"></td>
  </tr>
  <tr>
  <td>密码:</td>
  <td><input type="password" name="password"></td>
  </tr>
  <tr>
  <td align="center" colspan="2">
  <input type="submit" value="登录">
  </td>
  </tr>
  </table>
  </form>
     </center>
 </body>
 </html>

login_success.html 登录成功以后的提示的页面:

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>登录成功</title>
 </head>
 <body>
  <h1 align="center">恭喜您,登录成功!</h1>
 </body>
 </html>

login_fail.html登录失败提示的页面:

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>登陆失败</title>
 </head>
 <body>
  <h1 align="center">对不起,您所输入的用户名或密码错误,请重新登录!</h1>
 </body>

注意:form表单中的action属性中的提交业务路径可以不加./

2.在servlets包中添加LoginServlet.java,并定义好对应的service方法

(1)通过request对象获取用户名及其密码

 package cn.tedu.servlets;
 
 import java.io.File;
 import java.io.RandomAccessFile;
 import cn.tedu.http.HttpRequest;
 import cn.tedu.http.HttpResponse;
 /**
  * 处理用户登录业务逻辑的类
  * @author cjn
  *
  */
 public class LoginServlet {
  /**
   * 该方法用于处理登录的业务逻辑
  * @param request
  * @param response
  */
  public void service(HttpRequest request,HttpResponse response) {
  //1.获取用户进行登录时添写登录信息
  String userName = request.getParamters("username");
  String password = request.getParamters("password");
  System.out.println("用户名:" + userName + ",密码:" + password);
         
  //2.将user.txt文件中存储的用户和当前需要进行登录的用户做一个比对工作
  try (RandomAccessFile raf = new RandomAccessFile("user.txt", "rw")){
  //遍历所有用户
  for (int i = 0; i < raf.length()/100; i++) {
  raf.seek(i * 100);
  //读取存储在user.txt文件中用户的用户名
  byte[] data = new byte[32];
  raf.read(data);
  String name = new String(data, "utf-8").trim();
  if (name.equals(userName)) {
  /*
  * 如果用户名一致,证明登录的用户是已经注册过的用户,
  * 然后需要再进行比对密码是否一致
  */
  //取出存储在user.txt文件中该用户的密码
  raf.read(data);
  String pwd = new String(data, "utf-8").trim();
  //比对密码
  if (pwd.equals(password)) {
  //密码一致,响应一个登录成功的页面
  //3.当比对成功时,响应一个登录成功的页面
  response.setEntity(new File("webapps/myweb/login_success.html"));
  //已经响应登录成功页面,不需要再执行处理登录业务的方法
  return;
  }
  //找到该用户以后,就不需要去继续遍历其他用户了,终止循环
  break;
  }
  }
  //遍历了所有的用户都没有找到该用户,响应一个登录失败
  response.setEntity(new File("webapps/myweb/login_fail.html"));
  } catch (Exception e) {
  e.printStackTrace();
  }
  System.out.println("无论是你登录成功还是登录失败,登录业务完成");
  }
 
 }

(2)使用RandomAccessFile类读取user.txt中之前注册存储的每位用户的用户名和密码,如果可以匹配上,则设置response响应到login_success.html登录成功页面,否则设置response响应到login_fail.html登录失败页面。

3.在ClientHandler类中判断请求是否为注册业务,需要在if分支下再加一个else if判断,如果请求为登录业务,分支中实例化LoginServlet对象,并且调用service方法对登录业务进行操作。

 //业务路径的处理
 if ("/myweb/reg".equals(requestUrl)) {
  System.out.println("是注册业务");
  //处理注册业务
  RegServlet reg = new RegServlet();
  reg.service(request,response);
 } else if ("/myweb/login".equals(requestUrl)) {
  System.out.println("是登录业务");
     //处理登录业务
  LoginServlet login = new LoginServlet();
  login.service(request, response);
 } else {
     //资源路径的处理
     //webapps/myweb/index.html
     //webapps/myweb/谷歌.png
     File file = new File("webapps" + requestUrl);
     //判断是否可以找到index.html首页资源
     if (file.exists()) {
         System.out.println("找到资源页面");
         //找到首页资源
         //设置文件资源
         response.setEntity(file);
    } else {
         System.out.println("未找到资源页面");
         //未找到资源响应404页面
         File notFoundFile = new File("webapps/root/404.html");
         response.setStatusCode(404);
         response.setStatusReason("Not Found");
         response.setEntity(notFoundFile);
    }
 }

4.测试

  在浏览器输入:http://localhost:8888/myweb/login.html进行用户登录,输入注册过的用户信息(用户名和密码),当用户名和密码都输入正确时,响应登录成功页面,否则响应登陆失败页面。

登录业务流程图如下:

1.2 版本十二:重构HttpServlet

  1.在servlets包下定义一个超类HttpServlet,定义抽象方法:service,然后要求所有的Servlet都必须继承该类,这样可以规定所有的Servlet都必须具有service方法去实现各自的业务。

  2.将响应页面的逻辑提炼成一个方法,将相同的部分可以进行重用。

HttpServlet.java

 package cn.tedu.servlets;
 
 import java.io.File;
 
 import cn.tedu.http.HttpRequest;
 import cn.tedu.http.HttpResponse;
 
 /**
  * 所有Servlet的超类
  * @author cjn
  *
  */
 public abstract class HttpServlet {
  /**
  * 处理业务的抽象方法
  * @param request
  * @param response
  */
  public abstract void service(HttpRequest request,HttpResponse response);
 
  /**
  * 响应页面逻辑的方法
  * @param path
  * @param request
  * @param response
  */
  public void forward(String path,HttpRequest request,HttpResponse response){
  response.setEntity(new File("webspps"+path));
  }
 }
 

LoginServlet.java

 package cn.tedu.servlets;
 
 import java.io.File;
 import java.io.RandomAccessFile;
 import cn.tedu.http.HttpRequest;
 import cn.tedu.http.HttpResponse;
 /**
  * 处理用户登录业务逻辑的类
  * @author cjn
  *
  */
 public class LoginServlet extends HttpServlet{
  /**
   * 该方法用于处理登录的业务逻辑
  * @param request
  * @param response
  */
  public void service(HttpRequest request,HttpResponse response) {
  //1.获取用户进行登录时添写登录信息
  String userName = request.getParamters("username");
  String password = request.getParamters("password");
  System.out.println("用户名:" + userName + ",密码:" + password);
         
  //2.将user.txt文件中存储的用户和当前需要进行登录的用户做一个比对工作
  try (RandomAccessFile raf = new RandomAccessFile("user.txt", "rw")){
  //遍历所有用户
  for (int i = 0; i < raf.length()/100; i++) {
  raf.seek(i * 100);
  //读取存储在user.txt文件中用户的用户名
  byte[] data = new byte[32];
  raf.read(data);
  String name = new String(data, "utf-8").trim();
  if (name.equals(userName)) {
  /*
  * 如果用户名一致,证明登录的用户是已经注册过的用户,
  * 然后需要再进行比对密码是否一致
  */
  //取出存储在user.txt文件中该用户的密码
  raf.read(data);
  String pwd = new String(data, "utf-8").trim();
  System.err.println("注册过的用户对应的密码" + pwd);
  //比对密码
  if (pwd.equals(password)) {
  //密码一致,响应一个登录成功的页面
  //3.当比对成功时,响应一个登录成功的页面
 // response.setEntity(new File("webapps/myweb/login_success.html"));
  forward("/myweb/login_success.html", request, response);
  //已经响应登录成功页面,不需要再执行处理登录业务的方法
  return;
  }
  //找到该用户以后,就不需要去继续遍历其他用户了,终止循环
  break;
  }
  }
  //遍历了所有的用户都没有找到该用户,响应一个登录失败
 // response.setEntity(new File("webapps/myweb/login_fail.html"));
  forward("/myweb/login_fail.html", request, response);
  } catch (Exception e) {
  e.printStackTrace();
  }
  System.out.println("无论是你登录成功还是登录失败,登录业务完成");
  }
 
 }

RegServlet.java

 package cn.tedu.servlets;
 
 import java.io.File;
 import java.io.RandomAccessFile;
 import java.util.Arrays;
 import cn.tedu.http.HttpRequest;
 import cn.tedu.http.HttpResponse;
 
 /**
  * 处理注册业务
  * @author cjn
  *
  */
 public class RegServlet extends HttpServlet{
 
  public void service(HttpRequest request, HttpResponse response) {
  /*
  * 1.从paramters这个Map中取出对应key的value值
  * 2.检查用户是否已经注册过
  * 3.将没有注册过的用户信息存储到user.dat文件中
  * 4.注册成功以后,响应一个注册成功的页面,反之注册失败响应注册失败的页面
  * username=包佳奇
  * password=123456
  * nickname=baozi
  * age=30
  */
  String userName = request.getParamters("username");
  String password = request.getParamters("password");
  String nickName = request.getParamters("nickname");
  Integer age = Integer.parseInt(request.getParamters("age"));
  System.out.println("用户名:" + userName + ",密码:" + password
  + ",昵称:" + nickName + ",年龄" + age);
 
  //创建文件对象
  try (RandomAccessFile raf = new RandomAccessFile("user.txt", "rw");){
  //判断该用户是否已经注册过,没有重复注册过的用户才可以进行执行下面注册的逻辑
  for (int i = 0; i < raf.length()/100; i++) {
  //文件中有多少个用户就循环多少次
  raf.seek(i * 100);
  //根据每位用户的开始位置读取该用户的用户名(去除空格)
  byte[] data = new byte[32];
  raf.read(data);
  String name = new String(data, "utf-8").trim();
  if (name.equals(userName)) {
  //将要注册的用户已经注册过,提示该用户已经注册过
 // response.setEntity(new File("webapps/myweb/reg_fail.html"));
  forward("/myweb/reg_fail.html", request, response);
  //结束处理注册业务的方法
  return;
  }
  }
 
  //将用户需要注册的信息存储到user.txt文件中,每个信息占用规定的字节
  //严谨性操作。后注册的用户不能覆盖掉之前注册的用户,移动到文件的末尾位置
  raf.seek(raf.length());
  //对用户名进行写出
  byte[] arrayName = userName.getBytes("utf-8");
  arrayName = Arrays.copyOf(arrayName, 32);
  raf.write(arrayName);
  //对密码进行写出
  byte[] arrayPassword = password.getBytes("utf-8");
  arrayPassword = Arrays.copyOf(arrayPassword, 32);
  raf.write(arrayPassword);
  //对昵称进行写出
  byte[] arrayNick = nickName.getBytes("utf-8");
  arrayNick = Arrays.copyOf(arrayNick, 32);
  raf.write(arrayNick);
  //对年龄进行写出
  raf.writeInt(age);
 
  System.out.println(userName+"用户注册完毕");
  //目前测试没有响应报空指针异常,给一个响应
 // response.setEntity(new File("webapps/myweb/reg_success.html"));
  forward("/myweb/reg_success.html", request, response);
  } catch (Exception e) {
  e.printStackTrace();
  }
  }
 
 }

测试:启动WebServer主类,然后打开浏览器,在浏览器的地址栏输入http://localhost:8888/myweb/reg.html请求,在注册页面上填写需要进行注册的用户信息,然后再进行访问http://localhost:8888/myweb/login.html请求,在登录页面上填写登录信息,然后进行点击登录测试。

 

posted @ 2021-07-22 23:26  Coder_Cui  阅读(136)  评论(0编辑  收藏  举报