Подтвердить что ты не робот

Доступ к Spring beans из представления Tiles (JSP)

В Spring MVC я могу получить доступ к моему beans в JSP, используя JstlView, подверженные действиюContextBeanNames (или 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>

EDIT: Я реализовал решение Skaffman.

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

}

Spring Конфигурация:

    <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. Я провел несколько тестов, но, возможно, нужно сделать намного больше.

4b9b3361

Ответ 1

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

Посмотрев на код, нет причин, по которым этот материал не мог быть помещен в AbstractUrlBasedView. Магия происходит в InternalResourceView.getRequestToExpose, и она отлично подходит для AbstractUrlBasedView.

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

Ответ 2

Вы пытались использовать 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>

Ответ 3

Как и в случае с Spring 3.0, теперь существует TilesViewResolver.

Подкласс класса UrlBasedViewResolver, поддерживающий TilesView (т.е. определения плиток) и пользовательских подклассов.

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

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

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