会话技术之登录状态的保持

在前面我们学习了Cookie和Session两种会话技术,这个也是比较主流的两种会话技术。除了Cookie、Session,会话技术还有重写Url、隐藏表单域两种,不过使用起来比较不方便,因此就不进行介绍了。

​那理论学完了,我们就通过几个小案例还动手实践下,今天这篇文章就带大家使用Cookie与Session来完成登录状态的保持。

1.前端页面

​首先,就是我们的登录页面,Login.jsp,其中只有一个form表单,包含两个输入框和一个提交按钮。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
	<form action="LoginServlet" method="post">
		<input name="username" type="text"/>
		<br />
		<input name="password" type="password" />
		<br />
		<input type="submit" value="提交">
	</form>
</body>
</html>

​除了登录页面,还有一个登录成功的显示页面,这个页面可以根据Session的状态来判断用户是否登录和登录是否已经过期(如用户半小时无任何操作,Session过期,需用户重新登录)。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<% if(session.getAttribute("userName") != null){
		out.print("<h1>欢迎:" + session.getAttribute("userName") + ",恭喜登录成功</h1>");
	} else{
		out.print("<h1>登录已过期,请重新登录</h1>");
		out.print("<a href='./Login.jsp'>重新登录</a>");
	}
	%>
</body>
</html>

2.Java代码

​页面上点击提交后,表单数据被提交到Servlet中,我们新建个LoginServlet,urlPattern默认,其中的doGet方法如下:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
  request.setCharacterEncoding("UTF-8");
  response.setContentType("text/html;charset=utf-8");

  String userName = request.getParameter("username");
  String password = request.getParameter("password");
  System.out.println("获取到的用户名为:" + userName + ", 密码为:" + password);

  UserService userService = UserService.getInstance();
  try {
    String result = userService.loginByNameAndPassword(userName, password);
    boolean isSuccess = false;
    // 登录成功
    if ("Success".equals(result)) {
      isSuccess = true;
      // 创建Session
      HttpSession session = request.getSession();
      // 将登录用户名绑定到Session中
      session.setAttribute("userName", userName);
      Cookie cookie = new Cookie("userName", userName);
      // 将Cookie添加到response中
      response.addCookie(cookie);
    } else {
      // 登录失败
      System.out.println("登录失败的原因为:" + result);
    }

    // 输出页面 简单演示Servlet如何输出页面信息,也可将下面的内容直接写在JSP页面中
    // 登录成功页面显示跳转成功页面链接
    // 登录失败页面显示重新登录链接
    PrintWriter out = response.getWriter();
    out.print("<html>");
    out.print("<head>");
    out.print("<title>登录结果</title>");
    out.print("</head>");
    out.print("<body>");
    // 登录成功输出的信息
    if (isSuccess) {
      out.print("<h1>欢迎你:" + userName + ",恭喜登录成功</h1>");
      out.print("<a href='./Success.jsp'>点击跳转成功页</a>");
    } else {
      out.print("<h1>对不起:" + userName + ",登录失败</h1>");
      out.print("<h1>失败原因:" + result + "</h1>");
      out.print("<a href='./Login.jsp'>重新登录</a>");
    }
    out.print("</body>");
    out.print("</html>");
  } catch (ClassNotFoundException | SQLException e) {
    e.printStackTrace();
  }
}

​ LoginServlet中使用的UserService,其代码如下:

// 用户Service
public class UserService {

	private static UserService instance;

	private static UserDao userDao = null;

	// 私有的构造函数,在UserService类外部无法调用
	private UserService() {
	}

	// 单例 懒汉式
	public static UserService getInstance() {
		// 第一次调用时初始化UserService、UserDao
		if (instance == null) {
			instance = new UserService();
			userDao = new UserDao();
		}
		return instance;
	}
  
  /**
	 * 根据用户名和密码来判断是否登录成功
	 * 
	 * @param name
	 * @param password
	 * @return Success || 失败原因
	 * @throws ClassNotFoundException
	 * @throws SQLException
	 */
	public String loginByNameAndPassword(String name, String password) throws 												ClassNotFoundException, SQLException {
		System.out.println("查询指定用户,用户名为:" + name);
		// 用户名为null, 抛出异常
		if (StringUtils.isNullOrEmpty(name)) {
			return "用户名不可为空";
		}
		User user = userDao.findUserByName(name);
		System.out.println("用户查询成功,查询到的用户为:" + user);
		if (user == null) {
			return "用户名不存在";
		}
		if (!user.getPassword().equals(password)) {
			return "密码错误";
		}
		return "Success";
	}
}

​UserService中的UserDao代码如下:

// 操作User
public class UserDao {
  
  /**
	 * 根据用户名查询对应的用户
	 * 
	 * @param name
	 * @return User || null
	 * @throws ClassNotFoundException
	 * @throws SQLException
	 */
	public User findUserByName(String name) throws ClassNotFoundException, SQLException {
		Connection connection = null;
		PreparedStatement statement = null;
		ResultSet resultSet = null;
		try {
			// 获取数据库连接
			connection = JDBCUtil.getConnection();
			String sql = "SELECT * FROM users WHERE name = ?";
			// 创建PrepareStatement对象
			statement = connection.prepareStatement(sql);
			// 设置参数
			statement.setString(1, name);
			// 获取查询结果集
			resultSet = statement.executeQuery();
			User user = null;
			while (resultSet.next()) {
				user = new User();
				user.setId(resultSet.getInt("id"));
				user.setUserName(resultSet.getString("name"));
				user.setPassword(resultSet.getString("password"));
				user.setEmail(resultSet.getString("email"));
				user.setBirthday(resultSet.getDate("birthday"));
			}
			return user;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw e;
		} catch (SQLException e) {
			e.printStackTrace();
			throw e;
		} finally {
			JDBCUtil.release(resultSet, statement, connection);
		}
	}
  
}

​关于JDBCUtil、User、库表的创建可以参考这篇博文:https://lizishudd.blog.csdn.net/article/details/105088043。

3.测试

​为了方便测试,我截取数据库中User表中的部分数据。

资源分配图

​首先浏览器中输入Url,进入Login.jsp页面,输入正确的用户名、密码,点击登录,可以进入如下页面:

资源分配图

​点击舔砖成功页连接后,页面如下:

资源分配图

​此时,已经登录成功了,页面上也显示了已登录的账户名,刷新页面并不会影响结果。为了快速测试Session失效的场景,同时验证下JESSIONID和Session的关联性,我们将JESSIONID的稍作修改,如下图所示(随意修改,和原有的值不同即可):

资源分配图

​刷新页面后,页面显示结果如下,可以看到,因为JESSIONID被修改了,所以这里会因找不到对应的Session而创建一个新的Session,因此浏览器中的JESSIONID的值也被更新了。

资源分配图

​当我们在此基础上重新登录后,可以发现,JESSIONID如上图一样保持不变,我们的登录信息也保存在此session上。

4.小结

​本文简单的讲解了如何使用Session来保持我们的登录信息的,其主要操作就是在与客户端对应的Session中绑定一个属性(setAttribute),只要Session未过期,此次登录就一直有效。
当然Session还可以保持其他的会话信息,Session技术的出现就是为了方便解决会话数据的保持,我们可以将数据存储到Session中,然后在JSP中非常方便的拿到,一个方便使用的前后端数据传送门。


​又到了分隔线以下,本文到此就结束了,本文内容全部都是由博主自己进行整理并结合自身的理解进行总结,如果有什么错误,还请批评指正。

​Java web这一专栏会是一个系列博客,喜欢的话可以持续关注,如果本文对你有所帮助,还请还请点赞、评论加关注。

​有任何疑问,可以评论区留言。

发布了55 篇原创文章 · 获赞 941 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_34666857/article/details/105585904
今日推荐