Reputation: 501
I have two controllers that inherited from one, MainController. The Scope of every Controller is 'session'. In MainController I have one variable: Index, just follow:
@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++;
}
}
}
When "Action1" runs, Index is increase by 1 (ModelAttribute annotation) in MainController. In C1 variable is increasing by 1 every request, but in C2 is still 0 (as defined).
It is possible to 'inject' current value of Index to C2?
Upvotes: 3
Views: 1831
Reputation: 501
I resolved my problem like Martin Frey wrote. I've created Index as a session bean and Controllers can be Scope request.
The main tags to resolve problem was: scope="session" and aop:scoped-proxy in bean XML.
Here is an improved code:
@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());
}
}
And BaseController is:
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 class:
public class BeanSession {
private int Index;
public BeanSession() {
this.Index = 1;
}
public int getIndex() {
return Index;
}
public void setIndex(int index) {
Index = index;
}
}
And Bean definition in xml:
<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>
And that it works like I want to.
Upvotes: 0
Reputation: 10075
I would not put the controllers themself into the sessionscope.
Rather implement your sessionobject holding the index variable in the sessionscope and wire this into your controller.
I see at least three advantages:
Upvotes: 1
Reputation: 4251
If you want to count the number of times a user accesses the site there are several ways. One simple way is to create a servlet filter that's mapped to all requests that increments a request count and places it in the user's session.
This goes in 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>
The filter implementation would look something like this:
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
}
}
Upvotes: 4
Reputation: 41123
Although C1 and C2 are subclass of MainController, when spring boots it will create an instance of each, hence you have two copies of the variable Index
.
Easiest way is to make Index variable static such that it belongs to the class instance, not to the object
Try print some debug statement on the constructor of each C1 and C2 and when spring boots you'll see they're both different object instance
Upvotes: 1