Доступ к бобам Spring из представления Tiles (JSP) - PullRequest
19 голосов
/ 17 мая 2010

В Spring MVC я могу получить доступ к своим bean-компонентам в JSP, используя visibleContextBeanNames JstlView (или exposeContextBeansAsAttributes). Например, в моем JSP я могу написать ($ {properties.myProperty). Но когда тот же JSP является частью представления плиток, эти свойства недоступны. Можно ли правильно настроить плитки или получить доступ к этим свойствам по-другому?

Я использую Spring MVC 3.0.2 и Tiles 2.2.1. Вот немного моей конфигурации:

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

РЕДАКТИРОВАТЬ: Я реализовал решение Скаффмана.

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:

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);
    }

}

Конфигурация пружины:

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

Если у вас возникли проблемы, взгляните на TilesExposingBeansView.renderMergedOutputModel. Я сделал несколько тестов, но, возможно, нужно сделать гораздо больше.

Ответы [ 3 ]

13 голосов
/ 08 июля 2013

Вы пытались использовать ServletContextAttributeExporter в файле конфигурации 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>
12 голосов
/ 17 мая 2010

Как вы заметили, эта функциональность является частью InternalResourceViewResolver и InternalResourceView, тогда как материал Tiles наследуется непосредственно от UrlBasedViewResolver и AbstractUrlBasedView, поэтому вы не можете его использовать.

Глядя на код, нет причины, по которой этот материал нельзя было поместить в AbstractUrlBasedView. Волшебство происходит в InternalResourceView.getRequestToExpose, и оно выглядит вполне применимо и к AbstractUrlBasedView.

В краткосрочной перспективе я предлагаю создать подклассы UrlBasedViewResolver и TilesView, скопировав материал getRequestToExpose из InternalResourceView. В более долгосрочной перспективе я рекомендую вам подать проблему в SpringSource с просьбой переместить эту функцию вверх по иерархии классов в AbstractUrlBasedView, сделав ее более доступной.

1 голос
/ 18 марта 2012

Начиная с версии 3.0 теперь существует TilesViewResolver .

Удобный подкласс UrlBasedViewResolver, который поддерживает TilesView (т. е. определения плиток) и его подклассы.

Класс представления для всех представлений, созданных этим преобразователем, может быть указывается через свойство "viewClass". Смотрите UrlBasedViewResolver's Javadoc для деталей.

Примечание. При создании цепочки ViewResolvers TilesViewResolver проверяет наличие существование указанных ресурсов шаблона и только вернуть ненулевой Просмотр объекта, если шаблон был фактически найден.

С: 3.0 Автор: Юрген Хеллер

...