- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在做一个简单的网络项目(你可以看下面的代码)。据我所知, session 属性与一个 session 有关。当我打开同一浏览器的两个选项卡并运行键入 URL 时,只创建了一个 session ID,但同一 session 属性的两个不同对象正在运行(即我不想同时运行两个测验。但是,当我更改其中一个选项卡中的问题时,它不会影响另一个选项卡的 session 属性)。你能解释一下为什么会这样吗?如何更改我的代码以使 session 变量共享,以便当我更改其中一个选项卡中的 session 属性之一时,我希望其他选项卡的 session 变量受到影响?
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.quizServlet;
import QuizApp.Quiz;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
* @author Mati
*/
@WebServlet(name = "QuizServlet", urlPatterns = {"/Quiz"})
public class QuizServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
} catch (Exception ex) {
out.write("<font style='color:red'><b>" + ex.getMessage() + "</b></font>");
} finally {
out.close();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
if (request.getSession().getAttribute("QuizzObject") == null) {
Quiz quiz = new Quiz();
quiz.addQuestion(new int[]{1, 2, 3, 4});
quiz.addQuestion(new int[]{1, 1, 2, 3, 5, 8});
quiz.addQuestion(new int[]{0, 5, 10, 15, 20, 25});
request.getSession().setAttribute("QuizzObject", quiz);
}
if (request.getSession().getAttribute("questionsLeft") == null) {
request.getSession().setAttribute("questionsLeft", true);
}
Quiz qq = (Quiz) request.getSession().getAttribute("QuizzObject");
qq.reset();
StringBuilder SB = new StringBuilder();
SB.append("<form name='myform' method='post'>");
SB.append("<h3>Have fun with NumberQuiz!</h3>");
SB.append("<p><input type='submit' name='btnNext' value='Start quiz' /></p>");
SB.append("</form>");
out.print(SB.toString());
} catch (Exception ex) {
out.write("<font style='color:red'><b>" + ex.getMessage() + "</b></font>");
} finally {
out.close();
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
try {
StringBuilder SB = new StringBuilder();
String msg="";
SB.append("<html><head></head><body>");
Quiz qq = (Quiz) request.getSession().getAttribute("QuizzObject");
SB.append(request.getSession().getId());
boolean questionsLeft = (Boolean) request.getSession().getAttribute("questionsLeft");
if (questionsLeft) {
qq.addAttempts();
if (request.getParameter("txtAnswer") != null) {
if (qq.isCorrect(Integer.parseInt(request.getParameter("txtAnswer")))) {
qq.scoreAnswer();
} else {
msg="<p><font style='color:red'>Wrong Answer .. Try Again</font></p>";
}
}
if (qq.getCurrentQuestion() == null) {
request.getSession().setAttribute("questionsLeft", false);
SB.append("Congratulations, you have completed the quiz!");
SB.append("<br>Your final score is:" + qq.getScore());
SB.append("<br>Total attempts:" + qq.getAttempt());
qq.reset();
request.getSession().setAttribute("questionsLeft",null);
} else {
SB.append("<form name='myform' method='post'>");
//SB.append("<h3>Have fun with NumberQuiz!</h3>");
SB.append("<p>Your current score is " + qq.getScore() + ".</p>");
SB.append("<p>Guess the next number in the sequence!</p>");
SB.append("<p>" + qq.getCurrentQuestion().toString().replaceAll("\\?", "<font style='color:red'><b>?</b></font>") + "</p>");
SB.append("<p>Your answer:<input type='text' id='txtAnswer' name='txtAnswer' value='' /></p>");
SB.append("<p><input type='submit' name='btnNext' value='Next' onclick='return validate()' />");
SB.append("<input type='Reset' name='btnStart' value='Restart!' onclick=\"document.location.href='/QuizzWeb/Quiz';return false;\" /></p>");
SB.append(msg);
SB.append("</form>");
SB.append("<script type='text/javascript'>function validate(){if(document.getElementById('txtAnswer').value==''){alert('You should write an answer');return false;}return true;}</script>");
}
SB.append("</body></html>");
out.print(SB.toString());
}
} catch (Exception ex) {
out.print("<font style='color:red'><b>" + ex.getMessage() + "</b></font>");
} finally {
out.close();
}
}
@Override
public String getServletInfo() {
return "Short description";
}
}
最佳答案
我想你可能对一些概念有点混淆,希望这个解释能理解并帮助你理清头绪。
session 存在于您的应用程序服务器上。创建后,它会通过使用 cookie(通常名为 JSESSIONID)与您的浏览器进行通信。当您的浏览器将该 cookie 作为请求的一部分提供给网络服务器时,服务器可以检索已经附加到该 session 的 session 和关联对象(应该是可序列化的,请参阅其他 SO 问题)(前提是该 session 尚未过期).
由于这些 session 变量仅存在于服务器上,因此服务器使用它们来构建给客户端的响应。但是为了得到回应,您的客户需要提出请求。您提出了一个请求并更改了第一个选项卡的状态,但是因为第二个选项卡没有发出自己的请求,所以它的状态没有更新。 (因为这些选项卡在同一个浏览器中,它们共享一个 session cookie,并检索同一个 session 来满足它们的请求)。随着更多的构建,您可以利用一些客户端技术(例如 AJAX)定期发出有关 session 状态的小请求并刷新浏览器窗口的显示。 (您可以通过让它们调用不同的资源或请求的不同接受类型来区分此类请求)。
现在您的代码设计...我没有深入研究它,但您可能想要更多地完成您的流程。似乎 GET 总是会重置您的测验并且帖子会继续吗? (这对我来说感觉有点奇怪,但我无法解释为什么......我建议阅读 REST 以及由此驱动的设计。JAX-RS 和 Jersey 非常棒:))。
编辑:这是一个更简单的 servlet,您可以用来玩弄它。将其投入 war ,并打开 2 个选项卡,一个仅针对 servlet 本身,另一个附加查询字符串 ?checkOnly=true。尝试独立刷新每个选项卡,看看计数会发生什么。
package test.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Counting servlet counts the number of requests to it.
* @author Charlie Huggard-Lee
*/
@SuppressWarnings("nls")
public class CountingServlet extends HttpServlet {
/**
* The serialVersionUID.
*/
private static final long serialVersionUID = 4279853716717632192L;
/**
* {@inheritDoc}
*/
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
final HttpSession session = req.getSession();
AtomicInteger counter = (AtomicInteger) session.getAttribute("Count");
if (counter == null) {
counter = new AtomicInteger();
session.setAttribute("Count", counter);
}
final boolean checkOnly = Boolean.parseBoolean(req.getParameter("checkOnly"));
final int thisCount;
if (checkOnly) {
thisCount = counter.get();
} else {
thisCount = counter.getAndIncrement() + 1;
}
resp.setStatus(200);
resp.setHeader("Content-Type", "text/plain"); //$NON-NLS-1$ //$NON-NLS-2$
resp.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
final PrintWriter writer = resp.getWriter();
if (session.isNew()) {
writer.append("Hey new user!\n");
} else {
writer.append("Welcome Back!\n");
}
writer.append("Session ID: ");
writer.append(session.getId());
writer.append("\n");
if (checkOnly) {
writer.append("(checking) ");
}
writer.append("Count: ");
writer.append(Integer.toString(thisCount));
}
}
关于java - 使用同一浏览器的 2 个以上选项卡时,我的 Web 应用程序中 Servlet 中 Session 属性的范围和生命周期让我感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6003148/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!