0

私は webapp の liferay バージョンを 6.1.0 から 6.1.1 に移行中です ( liferay パッチャー コミュニティの 6.1.1-ga2 バージョンを使用しており、以前は機能していた web サービスに少し問題があります。

を使用しPortalDelegateServletて、春の DispatcherServlet をインスタンス化します。

私が抱えている問題は、サーブレット (myWS-servlet.xml) のスプリング コンテキストがアプリケーション コンテキストの前にインスタンス化されることです(スプリングからの同じ問題PortletContextLoaderListenerも試しました)。 ContextLoaderListener( がインスタンス化された時点ではロードされていませんDispatcherServlet)、スプリングはそれらを自動配線できません。

奇妙なことに、ポートレットを再デプロイすると問題が解決します。

どうすればこれを修正できるか分かりますか?


私の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>

私の 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 />

4

2 に答える 2

3

このスレッドが 1 年以上経過していることは知っています。しかし、私は人々の悩みを少しでも救いたいと思っていました。同僚と私は 1 週間かけて、Spring と PortalDelegateServlet + DispatcherServlet を使用して、ポートレット コントローラーの前に Spring サービスをロードできない理由を理解しようとしました。

他の投稿者がコメントしたように、問題http://issues.liferay.com/browse/LPS-29103とは多少関係がありますが、直接関係はありません。Liferay でサーブレットが初期化された方法と、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 メソッドに移動する場合があることです。そのため、ポートレット コントローラー内の AutoWired 要素には、すべての依存関係 (アプリケーション コンテキストからのサービス) がありません。

これを回避するために、web.xml 内で PortalDelegateServlet を宣言するのをやめ、PortalDelagateServlet と ServletConfig を新しくするカスタム ServletContextListener を作成し、同じパラメーターを 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) を呼び出します。

于 2014-07-29T19:19:31.593 に答える