Используйте разные View Resolver для каждого портлета - PullRequest
0 голосов
/ 19 декабря 2011

Можно ли настроить разные средства разрешения представления (все они типа JstlView) для разных портлетов?Моя структура каталогов JSP выглядит следующим образом:

+- WEB-INF
   |
   +- jsp
       |
       +- myorder
       |   |
       |   |- summary.jsp
       |   |
       |   |- edit-order.jsp
       |
       +- mydetails
       |   |
       |   |- summary.jsp
       |   |
       |   |- edit-details.jsp
       |
       |- error.jsp
       |
       |- success.jsp

( сгенерировано с использованием treegen )

У меня есть common.xml для обычного приложенияcontext и по одному для портлетов (mydetails-portlet.xml, myorder-portlet.xml).

У меня также есть несколько общих JSP, которые можно вызывать из любого портлета (error.jsp, success.jsp).

Определение viewResolver внутри common.xml выглядит следующим образом:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
    <property name="order" value="2" />
</bean>

Определение viewResolver внутри mydetails-portlet.xml выглядит следующим образом:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/mydetails/" />
    <property name="suffix" value=".jsp" />
    <property name="order" value="1" />
</bean>

И я ожидаювызовите error.jsp и edit-details.jsp, используя следующие строки в методе контроллера @RequestMapping, скажем, mydetails-portlet:

return "error";
return "edit-details";

Но наличие нескольких определений viewResolver для JstlView, похоже, переопределяетстарые, и я в конечном итоге получаю тот, который загружается последним.В результате я не могу правильно разрешить свои взгляды.

Есть ли другой способ достичь того, что я пытаюсь сделать, не прибегая к жестко закодированным путям, таким как return "mydetails/edit-details"?

Ответы [ 3 ]

2 голосов
/ 20 декабря 2011

Хорошо, я решил это, расширив InternalResourceViewResolver.Логика этого проста.Из-за природы InternalResourceViewResolver мы не можем действительно связать его с другим IRVR, если у нас не будет только одного IRVR, и он не появится в конце цепочки.

Итак, мы должны указать пружине значение return null при разрешении представлений на основе некоторого условия, которое вызовет запуск следующего IRVR в цепочке.

Для этого все, что я сделалЯ расширил IRVR и использовал предварительно сконфигурированный excludePrefix, который, если существует в имени представления, мой IRVR исключил бы его и вызвал цепочку.

Вот как выглядит мой ExcludingInternalResourceViewResolver:

public class ExcludingInternalResourceViewResolver extends
        InternalResourceViewResolver {

    private String excludePrefix;

    @Override
    public View resolveViewName(String viewName, Locale locale)
            throws Exception {

        if (this.excludePrefix != null && viewName.startsWith(this.excludePrefix)) {
            return null;
        }

        return super.resolveViewName(viewName, locale);
    }

    public void setExcludePrefix(String excludePrefix) {
        this.excludePrefix = excludePrefix;
    }
}

Ну, в основном у меня настроены два набора преобразователей представлений.Одна из них является обычной для обработки ошибок, страницы успеха, объявление которых выглядит так:

<bean id="commonViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
    <property name="order" value="3" />
</bean>

Другой, который находится внутри каждого портлета, выглядит так:

<bean id="viewResolver" class="com.foo.common.spring.web.view.ExcludingInternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/mydetails/" />
    <property name="suffix" value=".jsp" />
    <property name="order" value="1" />
    <property name="excludePrefix" value="common" />
</bean>

Мой обработчик ошибоквыглядит так:

<bean id="defaultExceptionHandler" class="org.springframework.web.portlet.handler.SimpleMappingExceptionResolver">
    <property name="order" value="2" />
    <property name="defaultErrorView" value="common/error" />
    <property name="exceptionMappings">
        <props>
            <prop key="javax.portlet.PortletException">common/portlet-error</prop>
        </props>
    </property>
</bean>

И наконец, я переместил свои error.jsp и portlet-error.jsp с /WEB-INF/jsp/ на /WEB-INF/jsp/common/.

1 голос
/ 22 июня 2012

Вы также можете использовать пакет ресурсов вместо файлов XML. Это сработало для меня.

Для этого вам понадобится файл any_name.properties комплекта, в котором ваши представления будут объявлены, как показано ниже, например,

У меня есть следующие jsp файлы портлета

WEB-INF / jsp / flight / bookingForm.jsp
WEB-INF / JSP / полета / bookingSuccess.jsp
WEB-INF / JSP / appError.jsp

Содержимое файла any_name.properties указано ниже. Обратите внимание, что за именами представлений следуют .(class) и .url в объявлении.


bookingForm.(class)=org.springframework.web.servlet.view.JstlView
bookingForm.url=/WEB-INF/jsp/flight/bookingForm.jsp

bookingSuccess.(class)=org.springframework.web.servlet.view.JstlView
bookingSuccess.url=/WEB-INF/jsp/flight/bookingSuccess.jsp

Этот пакет any_name.properties должен быть интегрирован в файл конфигурации appView-portlet.xml (при условии, что в вашем portlet.xml объявлен портлет appView ).

Если вы поместили any_name.properties в com.module.views пакет , вам потребуется выполнить настройку, как показано ниже.

<!-- View Resolver -->
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
       <property name="basenames">
          <list>
         <value>com.module.views.any_name</value>
           </list>
        </property>
    </bean>

Для appError.jsp вы можете иметь распознаватель представлений по умолчанию, если он есть, объявленный в вашем файле applicationContext.xml.

<!-- Default View Resolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="cache" value="true"/>
  <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
  <property name="prefix" value="/WEB-INF/jsp/"/>
  <property name="suffix" value=".jsp"/>
</bean>

Надеюсь, это поможет.

0 голосов
/ 19 декабря 2011

Да, вы можете сделать это. Spring-MVC обеспечивает соглашение по конфигурации. Прочитайте эту статью. Это поможет вам понять концепцию кок. В соответствии с требованием можно использовать разные страницы jsp из разных папок.

...