使用spring dm在karaf中配置hessian服务

时间:2015-03-09 13:13:28

标签: spring apache-karaf hessian pax-web

环境:

  • Karaf 3.0.1
  • Spring 3.2.4
  • Hessian 4.0.33

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

没有war或web.xml,只有plain beans + 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但是我找到了一个没有找到WebApplicationContext:没有注册ContextLoaderListener?

我已经跟踪了spring代码,内部jetty正在识别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。

1 个答案:

答案 0 :(得分:2)

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

以下是摘录:

<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。