Доступ к бинам Spring MVC DI из jsp
В некоторых средах MVC вы можете вызывать действия контроллера из представления, если вы хотите выполнить некоторый код и визуализировать некоторое частичное представление. Я не уверен, как правильно сделать это в Spring MVC
Я хочу иметь набор шаблонов JSP. Некоторые из них будут макетами страниц, некоторые из них будут небольшими компонентами, такими как paginator, окно входа в систему, меню, облако тегов и т. Д. И т. Д. И т. Д. Каждый из этих компонентов нуждается в некоторых bean-компонентах или контроллере для установки некоторых данных во ViewAndModel, чтобы представление могло использовать их.,
Проблема в том, что я не хочу устанавливать все эти объекты в каждом вызове. Мой контроллер регистраций заботится только об обработке регистрации. Итак, как мне это сделать правильно? Как вызвать DI-компоненты или контроллеры из представления для подготовки частичных представлений? Или я должен создать некоторые сопоставления? Или я подхожу к проблеме с совершенно неправильной точки зрения?
6 ответов
Spring-MVC может представить бины контекста приложения на уровне представления, если это то, что вы хотите сделать.
Например, InternalResourceViewResolver
может быть дано указание выставлять каждый компонент в контексте или только определенные. Посмотрите на свойства exposeContextBeansAsAttributes и extendedContextBeanNames.
Например, скажем, вы хотели выставить бобы beanA
а также beanB
к вашим JSP. Вы бы объявили преобразователь представления в вашем контексте следующим образом:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposedContextBeanNames">
<list>
<value>beanA</value>
<value>beanB</value>
</list>
</property>
</bean>
Кроме того, чтобы просто выставить каждый боб:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposeContextBeansAsAttributes" value="true"/>
</bean>
Является ли это хорошей идеей, это другой вопрос, но Spring дает вам возможность.
В IMO добавьте использование visibleContextBeanNames в конфигурации bean-компонента viewResolver (также есть возможность использовать глобальный флаг, но это не рекомендуется)
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposedContextBeanNames">
<list>
<value>beanName</value>
</list>
использовать в вашем JSP
${beanName.property}
Ты можешь использовать spring:eval
тег:
...
<spring:eval expression="@properties.getProperty('myProp')" var="myProp" />
${myProp}
...
куда @properties
имя бина ваших свойств в Spring Context. Обратите внимание, что этот подход не использует exposedContextBeanNames
, так что это может быть использовано с Tiles Views, например (TilesViewResolver
не имеет такого свойства).
Важной частью использования InternalResourceViewResolver является то, что Spring должен быть включен в поток кода при обработке страницы jsp. Если вы обращаетесь к странице jsp напрямую или иным образом, минуя любое действие на основе Spring (например, возможно, путем внутренней переадресации на страницу jsp из-за конфигурации входа в систему в web.xml), то это не сработает.
Однако можно настроить ваше приложение так, чтобы определенные bean-компоненты были доступны для всего, что может попасть в ServletContext (он же applicationScope), с помощью класса ServletContextAttributeExporter.
В вашей весенней конфигурации добавьте:
<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}
Очевидно, что это не сможет ссылаться на бины области запроса или сеанса, но если вам нужен доступ к одноэлементному бину, он отлично работает.
Никогда не обращайтесь к бизнес-компонентам из представлений jsp; что-то вроде sitemesh может быть использовано для объединения нескольких видов в одно. Jsps также не должен вызывать методы контроллера напрямую
Аннотационный подход к проблеме использования компонентов Spring в JSP.
Плитки Spring MVC + JSP:
@Bean
public ViewResolver tilesViewResolver() {
final UrlBasedViewResolver = new UrlBasedViewResolver();
...
viewResolver.setExposeContextBeansAsAttributes(true);
viewResolver.setExposedContextBeanNames("myBean");
return viewResolver;
}
И в моем .jsp:
<c:set var="myBeanData" scope="request" value="${myBean.myMethod()}"/>
<a id="id" href="${myBeanData}">Link</a>