1

与环境:

  • 卡拉夫 3.0.1
  • 春天 3.2.4
  • 黑森州 4.0.33

我已经通过 CXF 公开了一项服务,现在我正试图公开与 Hessian 服务相同的服务。

没有war或web.xml,只有普通bean + pax-http,我尝试了以下方法:

<bean name="/hessian" class="org.springframework.remoting.caucho.HessianServiceExporter">
    <property name="service" ref="promocionalOnLineWebServiceBean"/>
    <property name="serviceInterface" value="org.fideliapos.promos.webservice.PromocionalOnLineFacade"/>
</bean> 
...
<bean id="hessianServlet" class="org.springframework.web.context.support.HttpRequestHandlerServlet"/>
...
<osgi:service ref="hessianServlet" interface="javax.servlet.http.HttpServlet">
    <service-properties>
        <entry key="alias" value="/hessian"/>
    </service-properties>         
</osgi:service>

这个想法是注册一个 servlet(一个 HttpRequestHandlerServlet),其目标是一个 HessianServiceExporter,但我得到一个No WebApplicationContext found: no ContextLoaderListener registered?.

我跟踪了 spring 代码,内部码头正在识别 servlet 并调用它的 init 方法:

@Override
public void init() throws ServletException {
    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
    this.target = wac.getBean(getServletName(), HttpRequestHandler.class);
}

这就是问题所在,因为没有 spring WebApplicationContext 并且目标属性不能被注入。

我错过了什么吗?或者不可能让它像这样工作。

作为一种解决方法,我正在考虑使用我自己的实现(setTarget 等)扩展 Servlet,但我不想这样做。


更新

在尝试创建并添加我自己的 HttpContext 之后,仍然缺少一些东西:

我实现了自己的 HttpContext:

public class HessianContext implements HttpContext{
...
}

添加了豆子

<bean id="hessianContext" class="org.fideliapos.promos.hessian.HessianContext"/>

服务:

<osgi:service id="hessianContextService" ref="hessianContext" interface="org.osgi.service.http.HttpContext">
    <service-properties>
        <entry key="httpContext.id" value="hessian"/> <!-- also tried with contextId-->
    </service-properties>
</osgi:service>     

最后是作为服务的 servlet:

<osgi:service ref="hessianServlet" interface="javax.servlet.http.HttpServlet">
    <service-properties>
        <entry key="alias" value="/hessian"/>
        <entry key="httpContext.id" value="hessian"/> <!-- also tried with contextId-->      
    </service-properties>         
</osgi:service>

由于init 方法正在寻找 WebApplicationContext ,因此我应该声明并显式地声明 GenericWebApplicationContext bean,但我不知道如何将这个 bean 与 OSGi 所需的 HttpContext“加入”。

4

1 回答 1

2

看起来您需要将 Spring WebApplicationContext 添加到用于您的 servlet 的 HttpContext 中。现在你使用 Pax Web 的 DefaultHttpContext。在您的情况下,您需要注册一个知道 Spring 内容的自定义 HttpContext,以便WebApplicationContextUtils.getRequireWebApplicationContext能够提取此信息。为此,您需要将您的自定义 HttpContext 注册为服务并在您的 Servlet 中引用它,可以在此处找到使用蓝图(类似于 spring)的完整示例

以下是它的摘录:

<service id="forbiddenCtxtService" ref="forbiddenContext" interface="org.osgi.service.http.HttpContext">
    <service-properties>
        <entry key="httpContext.id" value="forbidden"/>
    </service-properties>
</service>

重要的部分是 httpContext.id

<bean id="forbiddenServlet" class="org.ops4j.pax.web.extender.samples.whiteboard.internal.WhiteboardServlet">
    <argument type="java.lang.String" value="/forbidden"/>
</bean>

<service id="forbiddenServletService" ref="forbiddenServlet" interface="javax.servlet.Servlet">
    <service-properties>
        <entry key="alias" value="/forbidden"/>
        <entry key="httpContext.id" value="forbidden"/>
    </service-properties>
</service>

同样,这里注册的 Servlet 确实有对应 httpContext.id 的配置,这会将这个 Servlet 绑定到之前注册的 HttpContext。

于 2015-03-10T07:40:04.260 回答