Интеграция Spring Beans и тегов JSP

Можно ли как-то интегрировать компоненты Spring и теги JSP в Spring. То есть использовать компонент Spring в качестве тега JSP? И если да, то это хорошая / ужасная идея? Итак, возможно что-то вроде этого:

@Component
public class SomeBean extends SimpleTagSupport {

    @Autowired
    SomeBean someBean;

    @Override
    public void doTag() throws JspException, IOException {
        getJspContext().getOut().write(someBean.doSomething());
    }
}

Что бы я сделал в tags.tld, чтобы заставить его использовать bean-компонент Spring вместо создания нового экземпляра, в который не было бы внедрено someBean? Или что-то еще?


person Derrops    schedule 20.12.2016    source источник


Ответы (1)


InternalResourceViewResolver позволяет использовать экспозицию для экспорта bean-компонентов в контекст jsp. Например, если вы хотите раскрыть список компонентов, вам следует настроить преобразователь представлений в себе dispatcher-servlet.xml следующим образом:

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

где someBean - имя bean-компонента, который вы хотите экспортировать в контекст jsp. Вы даже можете открыть все компоненты Spring:

   ...
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="prefix" value="/WEB-INF/views/"/>
       <property name="suffix" value=".jsp"/>
       <property name="exposeContextBeansAsAttributes" value="true"/>
   </bean>
   ...

Это позволяет вам получить доступ к компонентам Spring из контекста jsp по имени компонента.

Допустим, обработчик вашего тега выглядит так:

package com.mytags;
public class SomeTag extends SimpleTagSupport {

    private SomeBean bean;

    @Override
    public void doTag() throws JspException, IOException {
        getJspContext().getOut().write(bean.doSomething());
    }

    public SomeBean getBean(){...}
    public void setBean(SomeBean bean){...}
}

Тогда в tld ваш тег будет описан следующим образом:

...
<tag>
    <name>someTag</name>
    <tag-class>com.mytags.SomeTag</tag-class>
    <body-content>empty</body-content>
    <attribute>
        <name>bean</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
        <type>com.mybeans.SomeBean</type>
    </attribute>
</tag>
...

Обратите внимание, что вы должны указать rtexprvalue как true, потому что вы передадите bean-компонент в тег как выражение EL. Теперь вы можете использовать этот тег в jsp:

<%@ taglib prefix="mytags" uri="http://mytags.com" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title></title>
  </head>
  <body>
    <mytags:someTag bean="${someBean}"/>
  </body>
</html>

Но на самом деле не рекомендуется напрямую обращаться к Spring bean-компоненту из обработчика тега. Тег должен уметь отображать данные, но должен абстрагироваться от того, как получить эти данные. Лучше подготовьте все данные, которые вы хотите отобразить в контроллере, и передайте их в качестве модели в jsp.

person Ken Bekov    schedule 20.12.2016
comment
Спасибо, что написали такой исчерпывающий ответ, именно то, что я ищу. - person Derrops; 20.12.2016