我正在将我的webapp的liferay版本从6.1.0迁移到6.1.1(使用liferay patchers community中的6.1.1-ga2版本,并且我的webservices有点问题以前工作过。
我使用PortalDelegateServlet
来实例化一个Spring DispatcherServlet。
我遇到的问题是我的servlet(myWS-servlet.xml)的spring上下文在PortletContextLoaderListener
的应用程序上下文之前实例化(也是从spring ContextLoaderListener
尝试过的,同样的问题)
并且,由于我的控制器使用来自主应用程序上下文的服务(在DispatcherServlet
被实例化时未加载),因此spring无法自动装配它们。
奇怪的是,如果我重新部署我的portlet,问题就解决了。
你知道我怎么解决这个问题吗?
我的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>banner-portlet</display-name>
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>
<taglib-location>/WEB-INF/tlds/liferay-portlet.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://liferay.com/tld/theme</taglib-uri>
<taglib-location>/WEB-INF/tlds/liferay-theme.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://liferay.com/tld/portlet</taglib-uri>
<taglib-location>/WEB-INF/tlds/liferay-portlet-ext.tld</taglib-location>
</taglib>
</jsp-config>
<servlet>
<servlet-name>liferayWSdispatcher</servlet-name>
<servlet-class>com.liferay.portal.kernel.servlet.PortalDelegateServlet</servlet-class>
<init-param>
<param-name>servlet-class</param-name>
<param-value>org.springframework.web.servlet.DispatcherServlet</param-value>
</init-param>
<init-param>
<param-name>sub-context</param-name>
<param-value>rest-api</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>liferayWSdispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>com.liferay.portal.spring.context.PortletContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<!-- Instruct Mojarra to utilize JBoss-EL instead of the EL implementation
provided by the servlet container. -->
<!-- was used only for admin portlets but make calendar portlet crash
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
-->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<listener>
<listener-class>com.liferay.faces.portal.listener.StartupListener</listener-class>
</listener>
<!-- MyFaces will not initialize unless a servlet-mapping to the Faces Servlet
is present. -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>portalContextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-velocity-tool.xml</param-value>
</context-param>
我的applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="be.maximede">
<context:exclude-filter type="regex" expression="be.maximede.webservice.*"/>
</context:component-scan>
my myWS-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="be.maximede.webservice"/>
<mvc:annotation-driven />
答案 0 :(得分:3)
我知道这个帖子已经超过一年了。但我想帮助拯救人们一些麻烦。我和我的同事花了一个星期的时间试图弄清楚为什么我们不能在使用spring和PortalDelegateServlet + DispatcherServlet的portlet控制器之前加载spring服务。
与另一张海报评论的问题有点但并未与问题http://issues.liferay.com/browse/LPS-29103直接相关。它确实与在Liferay中初始化Servlet的方式以及Liferay如何处理web.xml重写有关。
Liferay重写了web.xml中定义的所有侦听器,并将它们放入上下文参数中,如下所示:
<context-param>
<param-name>portalListenerClasses</param-name>
<param-value>com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener,org.springframework.web.context.ContextLoaderListener</param-value>
</context-param>
然后创建自己的侦听器(或未显示,PluginContextListener):
<listener>
<listener-class>com.liferay.portal.kernel.servlet.SecurePluginContextListener</listener-class>
</listener>
然后,此SecurePluginContextListener将加载上下文并连接起来。问题是,有时,SecurePluginContextListener将首先使用Web应用程序上下文初始化PortalDelegateServlet,然后转移到portalListenerClasses中的init方法。因此,portlet控制器中的任何自动连接内容都缺少所有依赖项(来自应用程序上下文的服务)。
为了解决这个问题,我们放弃了在web.xml中声明PortalDelegateServlet并创建了一个自定义的ServletContextListener,它将新建一个PortalDelagateServlet和ServletConfig,并将相同的参数传递给spring的DispatcherServlet。这之所以有效,是因为我们让Liferay在portalListenerClasses中完成所有加载。重写的web.xml看起来像这样:
<context-param>
<param-name>portalListenerClasses</param-name>
<param-value>com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener,org.springframework.web.context.ContextLoaderListener, com.domain.CustomContextListener</param-value>
</context-param>
CustomContextListener将实现ServletContextListener中的方法。 在CustomContextListener的contextInitialized(...)方法中,我们只是以编程方式创建了我们在web.xml中使用的相同ServletConfig(实现ServletConfig的内部类)。然后我们创建一个pds = new PortalDelegateServlet()并调用pds.init(customServletConfig)
答案 1 :(得分:0)
对于Liferay 6.1.1,这是一个已知问题: