一、用户登录流程

在这里插入图片描述
当用户访问某个网站的首界面时:
首先会判断用户是否登录,如果已经登录则在首界面中显示用户登录信息,否则进入登录页面,完成用户登录功能,然后显示用户登录信息。
在用户登录的情况下,如果单击用户登录界面中的“退出”时,就会注销当前用户的信息,返回首界面。

二、实现步骤

需要创建的类和html:
User类:包含username和password两个属性,封装用户信息
IndexServlet类:用于显示网站首界面
LoginServlet类:用于显示登录成功后的界面
LogoutServlet类:用于完成用户退出时注销Session保存信息
Login.html:包含用户登录表单信息

(一)创建封装用户信息类

User类中包含username和password两个属性以及其getter和setter方法

public class User {
	private String username;
	private String password;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

(二)创建Servlet

(1)创建IndexServlet类,用于显示网站的首界面

public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		
		//创建或获取保存用户信息的Session对象//在相关的HttpSession 对象不存在时总是创建并返回新的HttpSession对象
		HttpSession session=request.getSession();
		
		//LoginServlet传过来的
		User user=(User)session.getAttribute("user");
		
		if(user==null) {
			response.getWriter().write("您还没有登录,请<a href='/chapter05/login.html'>登录<a>");
		}else {
			response.getWriter().write("您已登录,欢迎您,"+user.getUsername()+"先生/女士"+"!<br><br>");
			response.getWriter().write("<a href='/chapter05/LogoutServlet'>退出登录<a>");
			
			//创建Cookie存放Session的标识号
			Cookie cookie=new Cookie("JSESSIONID", session.getId());
			
			cookie.setMaxAge(60*30);
			//cookie适用路径
			cookie.setPath("/chapter05");
			response.addCookie(cookie);
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

(2)创建LoginServlet,显示登录成功后的界面

public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		String username = request.getParameter("username");
		String password = request.getParameter("password");

		PrintWriter pw = response.getWriter();
		
		// 假设正确的用户名 wangdong 密码101203
		if ("wangdong".equals(username) && "101203".equals(password)) {
			User user = new User();
			user.setUsername(username);
			user.setPassword(password);

			request.getSession().setAttribute("user", user);
			response.sendRedirect("/chapter05/IndexServlet");
		} else {
			pw.write("验证码错误,请重新登录!<br><br>");
			pw.write("3秒后将自动回到登录页面");
			response.setHeader("Refresh", "3;URL=http://localhost:8080/chapter05/login.html");
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}S

为了判断用户是否登录,该类在实现时,获取了保存用户信息的Session对象

(3)创建LogoutServlet类,用于完成用户退出时注销Session保存信息

public class LogoutServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//将Session对象中的User对象移除
		request.getSession().removeAttribute("user");
		response.sendRedirect("/chapter05/IndexServlet");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

(4)Login.html:包含用户登录表单信息

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户登录</title>
</head>

<body>
    <form action="/chapter05/LoginServlet" method="POST">
        用户名:<input type="text" name="username">
        <br>
        <br>&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="password" name="password">
        <br>
        <br>
        <input type="submit" value="登录" id="bt">
        <br>
    </form>
</body>
</html>

(三)运行结果

浏览器访问login.html
在这里插入图片描述
登录成功后:
在这里插入图片描述
关闭当前页面再次访问IndexServlet时显示还是登录状态,因为Cookie保存的Session对象还存在。
在这里插入图片描述
点击退出登录
在这里插入图片描述
点击退出登录后Session对象之前的数据已经被移除,此时再次点击登录则又需要重新输入用户名密码。
在这里插入图片描述

三、拓展——利用Session一次性验证码

(一) CheckServlet类

在上述类中增加一个CheckServlet类用于产生验证码图片(不细讲,因为我也不懂,此处手动滑稽😏)

public class CheckServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	// 验证码!!!
	private static int WIDTH = 60;// 验证码图片宽度
	private static int HEIGHT = 20;// 验证码图片高度

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		HttpSession session = request.getSession();
		response.setContentType("image/jpeg");

		ServletOutputStream sos = response.getOutputStream();
		// 设置浏览器不要缓存此图片
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);

		// 创建内存图像并获得其图形上下文
		BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
		Graphics g = image.getGraphics();

		// 产生随机的认证码
		char[] rands = generateCheckCode();

		// 产生图像
		drawBackground(g);
		drawRands(g, rands);

		// 结束图像的绘制过程,完成图像
		g.dispose();

		// 将图像输出到客户端
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ImageIO.write(image, "JPEG", bos);
		byte[] buf = bos.toByteArray();
		response.setContentLength(buf.length);

		// 下面的语句可换为bos.writeTo(sos);
		sos.write(buf);
		bos.close();
		sos.close();

		// 将验证码存放到Session中
		session.setAttribute("check_code", new String(rands));
		// 直接使用下面的代码将有问题,Session对象必须在提交响应前获得
		// request.getSession().setAttribute("check_code", new String(rands));

	}

	private char[] generateCheckCode() {
		// 定义验证码的字符表
		String chars = "0123456789abcdefghijklmnopqrstuvwxyz";
		char[] rands = new char[4];
		for (int i = 0; i < 4; i++) {
			int rand = (int) (Math.random() * 36);
			rands[i] = chars.charAt(rand);
		}
		return rands;
	}

	private void drawRands(Graphics g, char[] rands) {
		g.setColor(Color.BLACK);
		g.setFont(new Font(null, Font.ITALIC | Font.BOLD, 18));

		// 在不同的高度上输出验证码的每个字符
		g.drawString("" + rands[0], 1, 17);
		g.drawString("" + rands[1], 16, 15);
		g.drawString("" + rands[2], 31, 18);
		g.drawString("" + rands[3], 46, 16);

		System.out.println(rands);
	}

	private void drawBackground(Graphics g) {
		// 画背景
		g.setColor(new Color(0xDCDCDC));
		g.fillRect(0, 0, WIDTH, HEIGHT);

		// 随机产生120个干扰点
		for (int i = 0; i < 120; i++) {
			int x = (int) (Math.random() * WIDTH);
			int y = (int) (Math.random() * HEIGHT);
			int red = (int) (Math.random() * 255);
			int green = (int) (Math.random() * 255);
			int blue = (int) (Math.random() * 255);

			g.setColor(new Color(red, green, blue));
			g.drawOval(x, y, 1, 0);
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

(二)修改login.html和LoginServlet类

login.html修改

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户登录</title>
</head>

<body>
    <form action="/chapter05/LoginServlet" method="POST">
        用户名:<input type="text" name="username">
        <br>
        <br>&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="password" name="password">
        <br>
        <br>
    验证码:<input type="text" name="checkcode">
        <img alt="" src="/chapter05/CheckServlet">
        <br>
        <br>
        <input type="submit" value="登录" id="bt">
        <br>
    </form>
</body>
</html>

LoginServlet修改

public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		String username = request.getParameter("username");
		String password = request.getParameter("password");

		String checkCode = request.getParameter("checkcode");
		String savedCode = (String) request.getSession().getAttribute("checkcode");

		PrintWriter pw = response.getWriter();
		// 假设正确的用户名 wangdong 密码101203
		if ("wangdong".equals(username) && "101203".equals(password)&& checkCode.equals(savedCode)) {
			User user = new User();
			user.setUsername(username);
			user.setPassword(password);

			request.getSession().setAttribute("user", user);
			response.sendRedirect("/chapter05/IndexServlet");
		} else if (checkCode.equals(savedCode)) {
			pw.write("用户名或密码错误,请重新登录!<br><br>");
			pw.write("3秒后将自动回到登录页面");
			response.setHeader("Refresh", "3;URL=http://localhost:8080/chapter05/login.html");
		} else {
			pw.write("验证码错误,请重新登录!<br><br>");
			pw.write("3秒后将自动回到登录页面");
			response.setHeader("Refresh", "3;URL=http://localhost:8080/chapter05/login.html");
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

(二)运行修改后的代码

浏览器访问login.html
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐