在前面我们学习了Cookie和Session两种会话技术,这个也是比较主流的两种会话技术。除了Cookie、Session,会话技术还有重写Url、隐藏表单域两种,不过使用起来比较不方便,因此就不进行介绍了。
那理论学完了,我们就通过几个小案例还动手实践下,今天这篇文章就带大家使用Cookie与Session来完成登录状态的保持。
首先,就是我们的登录页面,Login.jsp,其中只有一个form表单,包含两个输入框和一个提交按钮。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
登录
除了登录页面,还有一个登录成功的显示页面,这个页面可以根据Session的状态来判断用户是否登录和登录是否已经过期(如用户半小时无任何操作,Session过期,需用户重新登录)。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
<% if(session.getAttribute("userName") != null){
out.print("欢迎:" + session.getAttribute("userName") + ",恭喜登录成功
");
} else{
out.print("登录已过期,请重新登录
");
out.print("重新登录");
}
%>
页面上点击提交后,表单数据被提交到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("");
out.print("");
out.print("登录结果 ");
out.print("");
out.print("");
// 登录成功输出的信息
if (isSuccess) {
out.print("欢迎你:"
+ userName + ",恭喜登录成功");
out.print("点击跳转成功页");
} else {
out.print("对不起:"
+ userName + ",登录失败");
out.print("失败原因:"
+ result + "");
out.print("重新登录");
}
out.print("");
out.print("");
} 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。
为了方便测试,我截取数据库中User表中的部分数据。
首先浏览器中输入Url,进入Login.jsp页面,输入正确的用户名、密码,点击登录,可以进入如下页面:
点击舔砖成功页连接后,页面如下:
此时,已经登录成功了,页面上也显示了已登录的账户名,刷新页面并不会影响结果。为了快速测试Session失效的场景,同时验证下JESSIONID和Session的关联性,我们将JESSIONID的稍作修改,如下图所示(随意修改,和原有的值不同即可):
刷新页面后,页面显示结果如下,可以看到,因为JESSIONID被修改了,所以这里会因找不到对应的Session而创建一个新的Session,因此浏览器中的JESSIONID的值也被更新了。
当我们在此基础上重新登录后,可以发现,JESSIONID如上图一样保持不变,我们的登录信息也保存在此session上。
本文简单的讲解了如何使用Session来保持我们的登录信息的,其主要操作就是在与客户端对应的Session中绑定一个属性(setAttribute),只要Session未过期,此次登录就一直有效。
当然Session还可以保持其他的会话信息,Session技术的出现就是为了方便解决会话数据的保持,我们可以将数据存储到Session中,然后在JSP中非常方便的拿到,一个方便使用的前后端数据传送门。
又到了分隔线以下,本文到此就结束了,本文内容全部都是由博主自己进行整理并结合自身的理解进行总结,如果有什么错误,还请批评指正。
Java web这一专栏会是一个系列博客,喜欢的话可以持续关注,如果本文对你有所帮助,还请还请点赞、评论加关注。
有任何疑问,可以评论区留言。