Apache Tomcat下MS SQL查询响应混淆问题求助及优化建议
问题根源与解决方案
核心问题
你遇到的查询响应混淆,本质是JSP页面的全局变量被多线程共享。Tomcat会把JSP编译成Servlet,Servlet实例是单例的,所有请求共用同一个实例。如果你的代码里用了类级别的变量(比如<%! %>块定义的变量)存储客户端选择的读卡器ID,多个客户端的请求会互相覆盖这些变量值,导致展示错误信息。
修复步骤
- 移除全局共享变量:把存储读卡器选择的变量从
<%! %>移到<% %>块,或改用会话(Session)存储。每个客户端有独立的Session,能保证选择的读卡器ID不会互相干扰:<% // 提交读卡器选择时存入Session if(request.getParameter("reader1") != null){ session.setAttribute("selectedReader1", request.getParameter("reader1")); session.setAttribute("selectedReader2", request.getParameter("reader2")); } // 从Session读取当前客户端的选择 String reader1 = (String)session.getAttribute("selectedReader1"); String reader2 = (String)session.getAttribute("selectedReader2"); %> - 绑定查询参数到当前客户端:SQL查询必须使用从Session/Request获取的读卡器ID,同时用
PreparedStatement防止SQL注入:String sql = "SELECT TOP 1 emp_id, emp_image FROM events WHERE reader_id = ? ORDER BY event_time DESC"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, reader1); ResultSet rs = pstmt.executeQuery(); // 处理结果集并渲染页面 - 优化页面刷新方式:替换全页面刷新为AJAX局部刷新,只更新员工信息区域,避免状态丢失:
对应的setInterval(() => { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if(xhr.readyState === 4 && xhr.status === 200){ document.getElementById("emp-info-container").innerHTML = xhr.responseText; } }; xhr.open("GET", "fetchEmpInfo.jsp", true); xhr.send(); }, 800);fetchEmpInfo.jsp只返回员工信息的HTML片段,无需包含完整页面结构。
其他实现思路
- 使用MVC框架:比如Struts2、Spring MVC,将业务逻辑从JSP分离到Controller层,JSP仅负责视图渲染,从架构上避免JSP全局变量的线程安全问题。
- 前后端分离:后端用Servlet或Spring Boot编写REST接口,返回JSON格式的员工数据;前端用HTML+JS(或Vue/React)维护客户端选择状态,定时调用接口更新页面,彻底消除多客户端状态混淆的可能。
- WebSocket实时推送:替代定时轮询,服务器监听数据库事件变化,主动将最新员工信息推送给对应客户端,延迟更低、效率更高。
内容的提问来源于stack exchange,提问作者rohit kumar maurya
相关产品推荐
相关产品推荐

