2013-03-25 57 views
3

我有兩個從MainController繼承的控制器。每個控制器的範圍都是'會話'。在MainController我有一個變量:指數,只需按照:Spring MVC - 跨控制器的繼承變量值

@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++; 
     } 
    } 
} 

當 「措施1」 的運行,指數是1(註釋的ModelAttribute)的MainController增加。在C1變量中,每個請求增加1,但在C2中仍然爲0(如定義)。

可以將Index的當前值「注入」到C2中嗎?

回答

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

儘管C1和C2是MainController的子類,當春天的靴子會創建一個每個實例,因此您有兩個副本的變量Index

最簡單的方法是使指數靜態變量,使得它屬於類的實例,而不是對象

嘗試打印每個C1和C2,當春靴,你會看到的一些構造調試語句他們都是不同的對象實例

1

我不會把控制器自己放到sessionscope中。

而不是實現sessionobject在sessionscope中保存索引變量並將其連接到控制器。

我看到至少有三個好處:

  • 較小的會議
  • 不需要靜態
  • 易於擴展:如果您需要該指數在另一個地方突然它不是繼承的控制器你基地之一
0

我解決了我的問題,如馬丁弗雷寫道。我已經創建了Index作爲會話bean,並且控制器可以是Scope請求。

要解決問題的主要標記是:bean = XML中的scope =「session」和aop:scoped-proxy 。

下面是一個改進的代碼:

@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> 

而且它的工作原理與我想要的一樣。