2010-01-15 72 views
12

在一些MVC框架中,如果您希望執行一些代碼並渲染一些局部視圖,您可以從視圖中調用控制器操作。我不確定在Spring MVC中做什麼是正確的方法從jsp訪問Spring MVC DI bean

我想擁有一組JSP模板。其中一些將是頁面佈局,其中一些將是小組件,如paginator,登錄框,菜單,標籤雲等等等等。這些組件中的每一個都需要一些bean或控制器動作來將一些數據設置到ViewAndModel中,以便視圖可以使用它。

問題是我不想在每次調用中設置所有這些對象。我的註冊管理員只關心註冊處理。那麼現在我該如何做對了?如何從視圖調用DI bean或控制器來準備部分視圖?或者我應該創建一些映射?還是我從完全錯誤的角度來處理問題?

回答

37

Spring-MVC可以將應用程序上下文的bean暴露給視圖層,如果這是你想要做的。

例如,可以指示InternalResourceViewResolver公開上下文中的每個bean或僅指定的bean。看看exposeContextBeansAsAttributesexposedContextBeanNames屬性。

例如,假設您想將豆類beanAbeanB展示給您的JSP。你會在你的情況下這樣聲明的視圖解析:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="exposedContextBeanNames"> 
     <list> 
     <value>beanA</value> 
     <value>beanB</value> 
     </list> 
    </property> 
</bean> 

或者,只是揭露每個bean:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="exposeContextBeansAsAttributes" value="true"/> 
</bean> 

不管這是一個好主意是另一個問題,但春天確實給你選項。在視圖解析器的bean的配置

+1

優秀的回答: - ) 現在,一旦我將控制器暴露給jsp,我實際上可以調用它並獲取菜單實例。我不知道我該怎麼做到底,因爲我可以看到耦合可以快速增加,但至少我有辦法做到這一點! 再次感謝! – Art79 2010-01-15 14:48:18

0

永遠不要從jsp視圖訪問業務組件;像sitemesh這樣的東西可以用來將多個視圖合併爲一個。 jsps也不應該直接調用控制器方法

+0

很好,這就是我試圖找出,我如何將必要的事情傳遞給我的部分視圖文件,所以我不必在同一個控制器中啓動它們。我的控制器不應該關心其他ModelAndView屬性。 理想情況下,我會包括部分(或調用控制器動作),它會調用負責它的控制器並準備來自bean等的所有數據,然後它將被傳遞到局部視圖並呈現。 至少我認爲這對我很有用: - ) – Art79 2010-01-15 14:22:51

+0

如果部分視圖都是同一個請求 - 響應cyhcle的一部分,那麼主視圖可以設置所有部分視圖的所有模型數據(當然,請求參數) – les2 2010-01-15 14:26:36

+0

我的主視圖是home.jsp,它包含menu.jsp。 「設置所有模型數據」是什麼意思? 你的意思是這樣的嗎? 我在這裏的問題是我沒有想從每個我可以擁有的控制器設置$ {menu}實例。我希望在一個單獨的「模塊」中處理這個問題。 我認爲必須有一些簡單的方法來處理這種用例: - )即時只是新鮮的春天,不能看到它: - ) – Art79 2010-01-15 14:33:26

5

IMO 添加使用exposedContextBeanNames(也有可能使用全局標誌,它是相當不推薦)

<bean id="viewResolver" 
    class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
<property name="exposedContextBeanNames"> 
<list> 
    <value>beanName</value> 
</list> 

使用在你的JSP

${beanName.property} 
1

使用InternalResourceViewResolver的關鍵部分似乎是Spring需要參與代碼流,當jsp頁面正在處理中。 如果您直接訪問jsp頁面或繞過任何基於Spring的操作(例如,可能由於web.xml中的登錄配置而導致內部轉發到jsp頁面),那麼這將不起作用。

但是,可以配置您的應用程序,以便某些bean可以通過 類訪問ServletContext(又稱applicationScope)的任何內容。

在Spring配置,添加:

<bean id="mybean" .../> 
<bean class="org.springframework.web.context.support.ServletContextAttributeExporter"> 
    <property name="attributes"> 
     <map> 
      <entry key="attrname" value-ref="mybean"/> 
     </map> 
    </property> 
</bean> 

然後,在JSP頁面中,你可以訪問與該豆:

${applicationScope.attrname} 

,或者如果你知道你沒有一個「attrname 「在更具體的範圍內屬性,只是:

${attrname} 

很明顯,這將無法引用請求或s ession scope bean,但是如果你需要訪問一個singleton bean,那麼它的效果很好。

2

您可以使用spring:eval標籤:

... 
<spring:eval expression="@properties.getProperty('myProp')" var="myProp" /> 
${myProp} 
... 

@properties是你性質Spring上下文中一個bean的名字。請注意,此方法不使用exposedContextBeanNames,因此它可以與Tiles Views一起使用,例如(TilesViewResolver不具有這樣的propery)。