为每个Portlet使用不同的View Resolver

时间:2011-12-19 10:14:48

标签: java spring spring-mvc portlet

是否可以为不同的portlet配置不同的视图解析器(所有类型为JstlView)?我的JSP目录结构如下所示:

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

使用treegen生成

我有一个common.xml用于公共应用程序上下文,一个用于portlet(mydetails-portlet.xmlmyorder-portlet.xml)。

我还有一些可以从任何portlet(error.jspsuccess.jsp)调用的常见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的{​​{1}}的多个定义似乎会覆盖旧版本,我最终会得到最后加载的那个。因此,我无法正确解决我的观点。

有没有其他方法可以实现我想要做的事情,而无需使用return "mydetails/edit-details"这样的硬编码路径?

3 个答案:

答案 0 :(得分:2)

好的,我通过扩展InternalResourceViewResolver来解决这个问题。这背后的逻辑很简单。由于InternalResourceViewResolver的性质,除非我们只有一个IRVR并且它出现在链的末尾,否则我们无法将其与另一个IRVR链接起来。

因此,我们必须告诉spring 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>

进入每个portlet的另一个看起来像:

<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.jspportlet-error.jsp/WEB-INF/jsp/移到/WEB-INF/jsp/common/

答案 1 :(得分:1)

您还可以使用资源包而不是xml文件。这对我有用。

为此,您需要包含一个包含文件any_name.properties的文件,其中您的视图声明如下,例如。

我有以下portlet 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 portlet)。 / p>

如果您已将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>

希望它有所帮助。

答案 2 :(得分:0)

是的,你可以做到。 spring-mvc提供了配置约定。阅读this文章。它将帮助您理解coc的概念。可以根据需要使用来自不同文件夹的不同jsp页面。