如何解决Java嵌入式Tomcat中char数组每次页面重载就重置的问题
问题根因
- 你每次处理HTTP请求时都会执行这段循环,直接把之前已经猜对填好字母的
untilEmpty数组全部重置为下划线:
for (int i=0; i< currentWord.length();i++){ untilEmpty[i] = '_'; }
- HTTP是无状态协议,你当前用
static修饰的currentWord和untilEmpty是Servlet全局共享变量,所有访问服务的用户会共用同一份游戏进度,互相干扰,也没法为单个用户持久化保存进度。 - 你判断单词是否猜全的代码
if (Empty == "")用了引用相等判断,Java中字符串内容比较必须用equals()方法,这里就算全猜对也不会触发成功逻辑。
修复方案
改用HttpSession为每个用户单独保存游戏进度,仅在首次开启游戏时初始化目标单词和占位符数组,后续请求复用Session中保存的进度:
- 移除类层面的static变量声明,所有游戏状态存在Session中
- 调整初始化逻辑,仅当新用户第一次访问、Session中没有游戏状态时才做初始化
- 每次猜对字母后更新Session中保存的占位符数组,不要每次请求都重置
核心修改代码示例
// 从当前用户Session中获取游戏状态 HttpSession session = req.getSession(); String currentWord = (String) session.getAttribute("currentWord"); char[] untilEmpty = (char[]) session.getAttribute("untilEmpty"); String temp = req.getParameter("Word"); // 首次访问或重置游戏时初始化 if (temp == null || currentWord == null || untilEmpty == null) { currentWord = gameWord(); untilEmpty = new char[currentWord.length()]; // 仅初始化的时候填下划线,后续请求不执行 for (int i=0; i< currentWord.length();i++){ untilEmpty[i] = '_'; } session.setAttribute("currentWord", currentWord); session.setAttribute("untilEmpty", untilEmpty); } else { currentWord = temp; } // 后面你原有输出表单的逻辑保持不变,可加一行输出当前猜词进度给用户看 out.write(String.format("<p>当前进度:%s</p>", new String(untilEmpty)).getBytes()); // 原有输入校验、猜词逻辑保持不变,猜对更新untilEmpty后记得重新存回Session // ... 你原有猜字母比对的逻辑 ... // 比对完成后更新Session里的进度 session.setAttribute("untilEmpty", untilEmpty); // 成功判断改为内容比较 if (Empty.equals("")) { System.out.println("guessed whole word :)"); // 猜对后清除Session里的状态,准备下一轮游戏 session.invalidate(); }
额外优化建议
- 你隐藏域传
Word的逻辑可以去掉,目标单词存在Session里更安全,避免用户打开控制台修改隐藏域的值作弊 - 变量名
integer语义不明,建议改成isValidInput这类可读性更高的命名
内容的提问来源于stack exchange,提问作者jelly
相关产品推荐
相关产品推荐

