Доступ к бинам 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>
Другие вопросы по тегам