我正在做一个简单的Web项目(你可以看到下面的代码).据我所知,会话属性与一个会话相关.当我打开同一浏览器的两个选项卡并运行输入URL时,只创建了一个会话ID,但同一个会话属性的两个不同对象正在运行(即我不想同时运行两个测验.但是,当我在其中一个标签中更改了问题时,它不会影响其他标签的会话属性).你能解释一下为什么会这样吗?如何更改我的代码以使会话变量共享,以便当我更改其中一个选项卡中的一个会话属性时,我希望其他选项卡的会话变量受到影响?
/*
* 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";
}
}
Run Code Online (Sandbox Code Playgroud)
我想你可能会有一些概念混乱,希望这个解释有意义并帮助你解决问题.
会话存在于您的应用程序服务器上.创建后,它会通过使用cookie(通常名为JSESSIONID)与您的浏览器进行通信.当您的浏览器将该cookie作为请求的一部分提供给Web服务器时,服务器可以检索已连接到该会话的会话和关联对象(应该是可序列化的,请参阅其他SO问题)(前提是此会话尚未过期) ).
由于这些会话变量仅存在于服务器上,因此服务器使用它们来构建给予客户端的响应.但是为了得到回复,您的客户需要提出请求.您发出了请求并更改了第一个选项卡的状态,但由于第二个选项卡没有自己的请求,因此状态尚未更新.(因为这些选项卡位于同一浏览器中,所以它们共享会话cookie,并检索相同的会话以满足其请求).通过更多的构建,您可以利用一些客户端技术(如AJAX)来永久地对会话状态做出小的请求并刷新浏览器窗口的显示.(您可以通过让他们在请求中调用不同的资源或不同的接受类型来区分这些请求).
现在你的代码设计......我没有深入研究它,但你可能想要更多地完成你的流程.似乎GET会一直重置您的测验并且帖子会继续吗?(这对我来说有些奇怪,但我无法理解为什么......我建议阅读REST和设计驱动的设计.JAX-RS和Jersey非常甜蜜:)).
编辑:这是一个可以用来玩的更简单的servlet.把它打成一个战争,打开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));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11202 次 |
| 最近记录: |