2010-05-17 14 views
19

Wiosną MVC Mogę uzyskać dostęp do moich ziaren w JSP przy użyciu odsłoniętychContextBeanNames JstlView (lub exposeContextBeansAsAttributes). Na przykład, w moim JSP mogę pisać ($ {properties.myProperty). Ale gdy ten sam JSP jest częścią widoku kafelków, właściwości te nie są dostępne. Czy można odpowiednio skonfigurować płytki lub uzyskać dostęp do tych właściwości w inny sposób?Uzyskiwanie dostępu do fasoli szparagowej z widoku kafli (JSP)

Używam Spring MVC 3.0.2 i Tiles 2.2.1. Oto nieco mojej konfiguracji:

<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> 
    <property name="order" value="1"/> 
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" /> 
</bean> 

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> 
    <property name="order" value="2"/> 
    <property name="prefix" value="/WEB-INF/views/"/> 
    <property name="suffix" value=".jsp"/> 
    <property name="exposedContextBeanNames"> 
     <list><value>properties</value></list> 
    </property> 
</bean> 

EDIT: I zostały wdrożone rozwiązanie Skaffman użytkownika.

TilesExposingBeansViewResolver.java:

package es.kcsolutions.util.spring.servlet.view; 

import org.springframework.web.servlet.view.*; 

public class TilesExposingBeansViewResolver extends UrlBasedViewResolver { 

    private Boolean exposeContextBeansAsAttributes; 
    private String[] exposedContextBeanNames; 

    public void setExposeContextBeansAsAttributes(boolean exposeContextBeansAsAttributes) { 
     this.exposeContextBeansAsAttributes = exposeContextBeansAsAttributes; 
    } 

    public void setExposedContextBeanNames(String[] exposedContextBeanNames) { 
     this.exposedContextBeanNames = exposedContextBeanNames; 
    } 

    @Override 
    protected AbstractUrlBasedView buildView(String viewName) throws Exception { 
     AbstractUrlBasedView superView = super.buildView(viewName); 
     if (superView instanceof TilesExposingBeansView) { 
      TilesExposingBeansView view = (TilesExposingBeansView) superView; 
      if (this.exposeContextBeansAsAttributes != null) view.setExposeContextBeansAsAttributes(this.exposeContextBeansAsAttributes); 
      if (this.exposedContextBeanNames != null) view.setExposedContextBeanNames(this.exposedContextBeanNames); 
     } 
     return superView; 
    } 

} 

TilesExposingBeansView.java: konfiguracja

package es.kcsolutions.util.spring.servlet.view; 

import java.util.*; 
import javax.servlet.http.*; 
import org.springframework.web.context.support.ContextExposingHttpServletRequest; 
import org.springframework.web.servlet.view.tiles2.TilesView; 

public class TilesExposingBeansView extends TilesView { 

    private boolean exposeContextBeansAsAttributes = false; 
    private Set<String> exposedContextBeanNames; 

    public void setExposeContextBeansAsAttributes(boolean exposeContextBeansAsAttributes) { 
     this.exposeContextBeansAsAttributes = exposeContextBeansAsAttributes; 
    } 

    public void setExposedContextBeanNames(String[] exposedContextBeanNames) { 
     this.exposedContextBeanNames = new HashSet<String>(Arrays.asList(exposedContextBeanNames)); 
    } 

    protected HttpServletRequest getRequestToExpose(HttpServletRequest originalRequest) { 
     if (this.exposeContextBeansAsAttributes || this.exposedContextBeanNames != null) 
     return new ContextExposingHttpServletRequest(originalRequest, getWebApplicationContext(), this.exposedContextBeanNames); 
     return originalRequest; 
    } 

    @Override 
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { 
     HttpServletRequest requestToExpose = getRequestToExpose(request); 
     exposeModelAsRequestAttributes(model, requestToExpose); 
     super.renderMergedOutputModel(model, requestToExpose, response); 
    } 

} 

Wiosna:

<bean id="tilesViewResolver" class="es.kcsolutions.util.spring.servlet.view.TilesExposingBeansViewResolver"> 
     <property name="order" value="1"/> 
     <property name="viewClass" value="es.kcsolutions.util.spring.servlet.view.TilesExposingBeansView"/> 
     <property name="exposedContextBeanNames"> 
      <list><value>properties</value></list> 
     </property> 
    </bean> 

Jeśli masz jakiś problem, przyjrzeć TilesExposingBeansView.renderMergedOutputModel. Zrobiłem kilka testów, ale może trzeba zrobić o wiele więcej.

+0

czy wziąłeś Google'a za integrację płytek wiosennych? – Bozho

+0

Tak, szukałem w Google. Mam pewne problemy z poprzednimi wersjami, ale teraz wszystko było ok, z wyjątkiem tego problemu. Szukałem go, ale niczego nie znalazłem :( – sinuhepop

+2

człowiek, wiosna i apache muszą napisać ci czek na to;) świetna robota – Ricardo

Odpowiedz

12

Jak już zauważyliśmy, ta funkcjonalność jest częścią InternalResourceViewResolver i InternalResourceView, natomiast rzeczy Płytki dziedziczy bezpośrednio od UrlBasedViewResolver i AbstractUrlBasedView, więc nie można z niego skorzystać.

Patrząc na kod, nie ma powodu, dla którego te rzeczy nie mogły zostać umieszczone w AbstractUrlBasedView. Magia dzieje się w InternalResourceView.getRequestToExpose i wygląda doskonale również w przypadku AbstractUrlBasedView.

W krótkim okresie sugeruję podklasy UrlBasedViewResolver i TilesView, kopiowanie rzeczy getRequestToExpose z InternalResourceView. W dłuższej perspektywie zachęcam do zgłoszenia problemu z numerem SpringSource z prośbą o przeniesienie tej funkcji do hierarchii klas do AbstractUrlBasedView, dzięki czemu będzie ona szerzej dostępna.

+0

Próbowałem czegoś podobnego, ale to nie działa. Podklasowałem JstlView, nadpisując wartości initServletContext, checkResource i renderMergedOutputModel. Spróbuję teraz twój pomysł. – sinuhepop

+0

@ Sinuhe: 'JstlView' nie będzie kompatybilny z Tiles, mechanizmy są zasadniczo różne. – skaffman

+0

Cóż, twoje rozwiązanie działało! Kiedy to robiłem, zauważyłem, że mój poprzedni pomysł nie był poprawny. Spróbowałem jeszcze trochę, zanim zgłoszę problem do SpringSource. Dzięki! – sinuhepop

1

Od wiosny 3.0 jest teraz TilesViewResolver.

wygoda podklasa UrlBasedViewResolver który obsługuje TilesView (tj definicje kwadraty) i Custom podklasy niego.

Klasa widoku dla wszystkich widoków wygenerowanych przez ten przelicznik może być określona za pomocą właściwości "viewClass". Szczegółowe informacje można znaleźć w artykule javadoc UrlBasedViewResolver.

Uwaga: Podczas łączenia ViewResolvers, A TilesViewResolver sprawdzi istnienie określonych zasobów szablonu i tylko zwrócić niezerowym Zobacz obiektu, jeśli szablon został rzeczywiście znaleźć.

Od: 3.0 Autor: Juergen Hoeller

+1

TilesViewResolver nie rozwiązuje problemu, ponieważ podklasuje UrlBasedViewResolver bez dodawania właściwości exposedContextBeanNames. Oryginalny post i zaakceptowana odpowiedź to nadal najlepszy sposób na przejście na AFAIK. – azpublic

13

Czy próbowałeś użyć ServletContextAttributeExporter w pliku konfiguracyjnym XML?

<bean 
    class="org.springframework.web.context.support.ServletContextAttributeExporter"> 
    <property name="attributes"> 
     <map> 
      <entry key="<bean key here>"> 
       <ref bean="<bean name here" /> 
      </entry> 
     </map> 
    </property> 
</bean> 
+2

Używam tego, ponieważ jest łatwiejsze do wdrożenia. – msangel

+0

Oczywiście Jest to bardziej elegancka i dyskretna metoda dodawania ziaren sesji! Miałem właśnie przedłużyć wiosenne zajęcia, twoje rozwiązanie uratowało moje kilkanaście dni pracy! DZIĘKUJĘ CI ! –

+0

To jest niesamowite. ** – user3120173

Powiązane problemy