Java Web开发TODO列表如何实现不同用户待办数据隔离
待办应用跨账号数据隔离实现方案
你遇到的不同账号看到相同待办内容的问题,核心原因是待办数据没有和所属用户做绑定,数据查询、操作时没有按用户身份做过滤,按照以下步骤改造即可实现用户只能查看、操作自己的待办内容:
相关参考截图如下:

改造步骤
1. 调整数据库表结构
首先给todo表新增用户关联字段,标记每条待办的所属用户:
-- 新增user_id字段存储待办所属用户的ID ALTER TABLE todo ADD COLUMN user_id INT NOT NULL COMMENT '所属用户ID'; -- 给user_id加索引提升查询效率 ALTER TABLE todo ADD INDEX idx_user_id(user_id);
前提:你需要先完成用户登录模块开发,用户登录校验通过后,将当前登录用户的ID存入服务端Session。
2. 扩展Model实体类
给待办Model类新增userId属性及对应的get/set方法:
public class Model { private int ID; private String TODO; private int userId; // 新增:所属用户ID public Model() { super(); } public Model(int iD, String tODO, int userId) { super(); ID = iD; TODO = tODO; this.userId = userId; } public int getID() { return ID; } public void setID(int iD) { ID = iD; } public String getTODO() { return TODO; } public void setTODO(String tODO) { TODO = tODO; } // 新增userId的get/set方法 public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } }
3. 改造Dao层数据操作逻辑
所有待办相关的增删改查SQL,都必须带上user_id作为过滤条件,从数据层避免越权访问:
public class Dao { private final static String url = "jdbc:mysql://localhost:3306/todolist"; private final static String user = "root"; private final static String password = ""; private final static String dbloader = "com.mysql.jdbc.Driver"; // 修改新增待办SQL,写入时绑定user_id private final static String ADD = "INSERT INTO `todo`(`TODO`,`user_id`) VALUES (?,?)"; // 新增:查询指定用户的待办列表SQL private final static String QUERY_USER_TODOS = "SELECT ID, TODO, user_id FROM todo WHERE user_id = ?"; // 新增:删除待办时必须同时校验待办ID和所属用户ID,防止越权删除 private final static String DELETE_TODO = "DELETE FROM todo WHERE ID = ? AND user_id = ?"; // 新增:更新待办时同样要校验用户ID private final static String UPDATE_TODO = "UPDATE todo SET TODO = ? WHERE ID = ? AND user_id = ?"; public static void Driver(String dbloader) { try { Class.forName(dbloader); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() { Connection con = null; try { con = DriverManager.getConnection(url, user, password); } catch (Exception e) { e.printStackTrace(); } return con; } public static int ADDTODO(Model mod) { int i = 0; Connection con = null; PreparedStatement pst = null; try { Driver(dbloader); con = getConnection(); pst = con.prepareStatement(ADD); pst.setString(1, mod.getTODO()); pst.setInt(2, mod.getUserId()); // 绑定当前用户ID i = pst.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { // 补全资源释放逻辑,避免数据库连接泄漏 try { if (pst != null) pst.close(); if (con != null) con.close(); } catch (Exception e) { e.printStackTrace(); } } return i; } // 新增:查询指定用户的待办列表方法 public static List<Model> getUserTodoList(int userId) { List<Model> todoList = new ArrayList<>(); Connection con = null; PreparedStatement pst = null; ResultSet rs = null; try { Driver(dbloader); con = getConnection(); pst = con.prepareStatement(QUERY_USER_TODOS); pst.setInt(1, userId); rs = pst.executeQuery(); while (rs.next()) { Model item = new Model(); item.setID(rs.getInt("ID")); item.setTODO(rs.getString("TODO")); item.setUserId(rs.getInt("user_id")); todoList.add(item); } } catch (Exception e) { e.printStackTrace(); } finally { // 释放资源 try { if (rs != null) rs.close(); if (pst != null) pst.close(); if (con != null) con.close(); } catch (Exception e) { e.printStackTrace(); } } return todoList; } }
4. 改造Servlet层逻辑
从服务端Session中获取当前登录用户ID,禁止从前端请求参数中接收用户ID(防止参数篡改越权):
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 登录校验:未登录直接跳转登录页 HttpSession session = request.getSession(); Object loginUserIdObj = session.getAttribute("loginUserId"); if (loginUserIdObj == null) { response.sendRedirect("login.jsp"); return; } int loginUserId = (Integer) loginUserIdObj; String todoContent = request.getParameter("todo"); Model mod = new Model(); mod.setTODO(todoContent); mod.setUserId(loginUserId); // 给新待办绑定当前登录用户ID Dao dao = new Dao(); int res = dao.ADDTODO(mod); if (res > 0) { response.sendRedirect("Userpage.jsp"); } }
5. 调整Userpage.jsp数据加载逻辑
页面加载待办列表时,调用getUserTodoList方法传入当前登录用户ID,只查询当前用户自己的待办数据渲染到表格,禁止查询全表待办数据。
你提供的原有页面表单代码如下,不需要大改,只需要把后端查询到的当前用户待办列表循环渲染到表格区域即可:
<form action="Addtodo" method="post"> <div class="add-items d-flex"> <input type="text" class="form-control todo-list-input" name="todo" placeholder="What do you need to do today?"> <button type="submit" class="btn btn-success btn-lg btn-block" value="add" >Add</button> </div> </form>
核心注意事项
- 所有待办的增、删、改、查操作,都必须以服务端Session中存储的登录用户ID作为过滤条件,绝对不能信任前端传来的用户ID参数
- 删除、修改待办时,必须同时校验待办ID和当前用户ID,避免用户通过修改待办ID参数操作其他人的待办
- JDBC操作后必须及时释放Connection、PreparedStatement、ResultSet资源,否则会出现数据库连接泄漏,服务运行一段时间后会无法连接数据库
内容的提问来源于stack exchange,提问作者Benjie Alcontin
相关产品推荐
相关产品推荐

