gpt4 book ai didi

java - Spring MVC 中的 HTTP session

转载 作者:行者123 更新时间:2023-11-29 06:44:06 26 4
gpt4 key购买 nike

我正在使用 spring mvc 创建一个非常简单的测验应用程序。它工作正常。但是现在,如果用户正在回答第三个问题,并且另一个请求来自另一个浏览器(另一个用户),它将向新用户呈现第四个问题。我不希望这发生。每个新请求都应该从第一个问题开始测验。我如何在没有为每个用户提供登录表单的情况下实现这一点,并将来自不同浏览器的每个新请求识别为不同的用户?我知道这可以通过 session 来实现。

谁能解释一下如何做到这一点?

package dmv2.spring.controller;

import java.util.List;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import dmv2.form.QuestionForm;
import dmv2.model.Exam;
import dmv2.model.Question;

@Controller
@SessionAttributes
@RequestMapping("/Exam")
public class ExamController
{
private List<Question> questions = (new Exam()).getQuestions();
private int index = 0;
private int score = 0;

@RequestMapping(method = RequestMethod.GET)
public ModelAndView showQuestionForm()
{
Question q = questions.get(index);
return new ModelAndView("exam", "questionForm", new QuestionForm()).addObject("q", q);
}

@RequestMapping(method = RequestMethod.POST)
public ModelAndView showQuestionForm2(@ModelAttribute("questionForm") QuestionForm questionForm, BindingResult result)
{
Question q = questions.get(index);
if(q.getAnswer().getRightChoiceIndex() == Integer.parseInt(questionForm.getChoice()))
score = score + 1;
index = index + 1;
if(index < questions.size())
{
q = questions.get(index);
}
else
return new ModelAndView("result").addObject("score", score);
return new ModelAndView("exam", "questionForm", new QuestionForm()).addObject("q", q);
}

}

最佳答案

永远不要将状态放在 Controller 中,就像在 Servlet 中一样,它对每个人都是全局的,并且必须同步访问它。一般来说,不要将任何可变内容作为 Controller 的字段放置是一个很好的规则。您甚至不应该将业务逻辑放在 Controller 中,您应该从服务层调用对象来完成所有使用强大服务的工作。

为了解决您的问题,您可以定义一个名为 QuestSession 的接口(interface),它将充当用户对话状态的代理。最好实现边界检查。 (我想 index 和 score 不能为负数,例如)。

public interface QuestSession {
public int getIndex();
public void setIndex(int index);
public int getScore();
public void setScore(int score);
}

接下来你只要在你需要的地方传递这个接口(interface),比如:

public ModelAndView showQuestionForm2(
@ModelAttribute("questionForm") QuestionForm questionForm,
BindingResult result, QuestSession session) {

要使其正常工作,您必须创建一个 QuestSessionImpl 并添加到您的 XML 配置中。

<bean id="questSessionImpl" class="package.QuestSessionImpl" scope="session">
<aop:scoped-proxy />
</bean>

aop:scoped-proxy 是面向方面的编程位,它可以神奇地代理您的类,因此每个 session 都将与不同的对象对话。您甚至可以在 Controller 字段上使用 @Autowired,每个 session 仍会收到不同的对象。

我不知道怎么用注释来表达,如果有人看这个知道,请指教。

一句警告。甚至 session 访问也不是线程安全的。当然,它比对单个字段的全局共享访问更不危险,但用户打开两个浏览器选项卡或窗口仍然有可能创建竞争条件。你开始感受到 AJAX 带来的所有痛苦,因为许多异步请求可以聚集在一起。即使您不使用 AJAX,您也可能想要添加适当的同步。

关于java - Spring MVC 中的 HTTP session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7949813/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com