我有两个继承自MainController的控制器。每个控制器的范围是“会话”。在MainController中我有一个变量:Index,只需按照:
@Controller
public class C1 extends MainController {
@RequestMapping(value="/action1")
public void Action1() {
System.out.print(Index);
}
}
@Controller
public class C2 extends MainController {
@RequestMapping(value="/action2")
public void Action2() {
System.out.print(Index);
}
}
public class MainController {
protected int Index = 0;
@ModelAttribute("BeforeRequest")
public void BeforeRequest(HttpServletRequest request) {
if (request.getRequestURI().contains("action1")) {
Index++;
}
}
}
当“Action1”运行时,Index在MainController中增加1(ModelAttribute注释)。在C1变量每个请求增加1,但在C2中仍然是0(定义)。
可以将“当前值”注入“C2”
答案 0 :(得分:4)
如果要计算用户访问网站的次数,有几种方法。一种简单的方法是创建一个servlet过滤器,该过滤器映射到所有递增请求计数的请求并将其放在用户的会话中。
这可以在web.xml中找到:
<filter>
<filter-name>RequestCountFilter</filter-name>
<filter-class>com.mycompany.RequestCountFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RequestCountFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器实现看起来像这样:
public class RequestCountFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession();
Integer requestCount = session.getAttribute("requestCount") == null 0 : session.getAttribute("requestCount");
session.setAttribute("requestCount", ++requestCount);
chain.doFilter(req, res);
}
public void init(FilterConfig config) throws ServletException {
// init code goes here
}
public void destroy() {
// clean up goes here
}
}
答案 1 :(得分:1)
虽然C1和C2是MainController的子类,但是当spring引导它时会创建每个的实例,因此你有两个变量Index
的副本。
最简单的方法是使Index变量为静态,使其属于类实例,而不是对象
尝试在每个C1和C2的构造函数上打印一些调试语句,当弹簧启动时,你会发现它们都是不同的对象实例
答案 2 :(得分:1)
我不会将控制器自己放入会话镜。
而是在sessionscope中实现保存索引变量的sessionobject并将其连接到控制器中。
我发现至少有三个优点:
答案 3 :(得分:0)
我像Martin Frey写的那样解决了我的问题。我已经将Index创建为会话bean,而控制器可以是Scope请求。
解决问题的主要标签是:scope =“session”和aop:scoped-proxy 在bean XML中。
这是一个改进的代码:
@Controller
@Scope("request")
public class C1 extends BaseController {
@RequestMapping(value="/action1")
public void Action1() {
System.out.println("Action1: " + Index.getIndex());
}
}
@Controller
@Scope("request")
public class C2 extends BaseController {
@RequestMapping(value="/action2")
public void Action2() {
System.out.println("Action2: " + Index.getIndex());
}
}
BaseController是:
public class BaseController {
@Autowired
protected BeanSession Index;
@ModelAttribute("BeforeRequest")
public void BeforeRequest(HttpServletRequest request) {
if (request.getRequestURI().contains("action1")) {
Index.setIndex(Index.getIndex() + 1);
}
}
public BeanSession getIndex() {
return Index;
}
public void setIndex(BeanSession index) {
Index = index;
}
}
BeanSession类:
public class BeanSession {
private int Index;
public BeanSession() {
this.Index = 1;
}
public int getIndex() {
return Index;
}
public void setIndex(int index) {
Index = index;
}
}
和xml中的Bean定义:
<bean id="BeanSession_Bean" class="controller.BeanSession" scope="session" >
<aop:scoped-proxy/>
</bean>
<bean id="BaseController_Bean" class="controller.BaseController">
<property name="Index" ref="BeanSession_Bean" />
</bean>
它就像我想要的那样。