【问题标题】:Jaxb2Marshaller and primitive typesJaxb2Marshaller 和原始类型
【发布时间】:2009-11-12 14:27:45
【问题描述】:

在 spring-ws 中使用 Jaxb2Marshaller 时,是否可以使用原始或基本 Java 类型创建 Web 服务操作?例如一个看起来像这样的方法:

@Override
@PayloadRoot(localPart = "AddTaskRequest", namespace = "http://example.com/examplews/")
public long addTask(final Task task) throws AddTaskFault {
 // do something
 return 0;
}

我正在使用 maven jaxws 插件从我的 WSDL 生成接口和模型类。当我尝试调用网络服务时,出现以下错误:

java.lang.IllegalStateException:端点没有适配器 [...]:您的端点是否实现了受支持的接口,例如 MessageHandler 或 PayloadEndpoint

我发现如果我将方法更改为:

@Override
@PayloadRoot(localPart = "AddTaskRequest", namespace = "http://example.com/examplews/")
public JAXBElement<Long> addTask(final JAXBElement<Task> task) throws AddTaskFault {
 final ObjectFactory objectFactory = new ObjectFactory();
 return objectFactory.createAddTaskResponse(0L);
}

我可以调用它——但是这个签名与 maven jaxws 插件生成的接口不兼容。

如何配置 spring-ws 以使用第一种实现或告诉 maven jaxws 插件生成接口的第二种变体?

更新:我的相关 spring-ws 配置条目如下所示:

<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
 <property name="contextPath" value="com.example.examplews" />
</bean>

<bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
 <constructor-arg ref="marshaller" />
</bean>

<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
 <property name="order" value="1" />
</bean>

【问题讨论】:

  • 你能发布你的spring xml配置吗?我有一个类似的问题,我通过配置解决了它......这是一段时间前,但如果你发布你的,我可以检查我的正确配置是什么并发布差异。

标签: java spring jaxb jax-ws spring-ws


【解决方案1】:

当 Spring-WS 尝试将 EndpointAdapter 匹配到 Endpoint 时,它会检查端点方法的所有参数以及它的返回值是否是 Jaxb2Marshaller 和 @987654324 已知的类型@ 将不会。从概念上讲,这是有道理的,因为 JAXB 不知道如何在没有更多信息的情况下将 long 转换为 XML(这就是 JAXBElement 的来源)。

您应该意识到 Spring-WS 不是 JAX-WS 实现,并且不假装是。您不能真的期望获取 JAX-WS 生成的工件并期望它们只在 Spring_WS 中工作,尽管在许多情况下 Spring-WS 足够灵活来处理它。

【讨论】:

  • 好的,那么以自上而下的方法使用 spring ws 的最佳方法是什么?我想用maven生成必要的类,这样我只需要实现web服务接口。
  • 我知道没有生成工具可以做到这一点,但是 Spring-WS 的代码非常简单,所以你不会真正节省那么多打字。
  • 所以你会建议使用自下而上的方式,只需将我的代码编写为我的 Web 服务接口?
  • Spring-WS 提倡首先编写您的 XML 模式,然后在 java 中编写端点来接收和响应符合该模式的文档。 WSDL 很自然地脱离了这个过程。
【解决方案2】:

这是我的配置中相关的所有内容,因为我真的不知道你可以改变什么,它们完全不同,我这样做已经一年半了。

    <bean id="schemaCollection"
        class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
        <property name="xsds" value="/my.xsd" />
        <property name="inline" value="true" />
    </bean>

    <bean id="marshallingEndpoint"
        class="....EndpointImpl">
    </bean>

    <oxm:jaxb2-marshaller id="marshaller" contextPath=".....schema" />

   <bean id="annotationMapping"      class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
        <property name="interceptors">
            <list>
                <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
                <bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
                    <property name="xsdSchemaCollection"
                        ref="schemaCollection" />
                    <property name="validateRequest" value="true" />
                    <property name="validateResponse" value="true" />
                </bean>
            </list>
        </property>
        <property name="order" value="1" />
    </bean>

    <sws:marshalling-endpoints />

希望它在某种程度上有所帮助。 Endpoint 类有@Endpoint,方法有@PayloadRoot。他们没有返回很长时间,但我也不必将我的类包装在 JAXBElement 中。

[编辑] 命名空间

    xmlns:oxm="http://www.springframework.org/schema/oxm"
    xmlns:sws="http://www.springframework.org/schema/web-services"

    xsi:schemaLocation="
       http://www.springframework.org/schema/oxm 
       http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd">

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    相关资源
    最近更新 更多