30

我正在为带有 JMS 的 Spring-WS 示例而苦苦挣扎。我按照 Spring 的建议设置了 Spring-WS 和 JMS 布线。但我不断收到以下错误。我不知道如何绕过这个问题,任何帮助将不胜感激:

[org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver] - 
Resolving exception from endpoint 
[org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
java.lang.IllegalStateException: No adapter for endpoint 
[org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?

[org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver] - Resolving exception from endpoint
[org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
java.lang.IllegalStateException: No adapter for endpoint [org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?

[org.springframework.ws.soap.server.SoapMessageDispatcher] - 
Endpoint invocation resulted in exception - responding with Fault
java.lang.IllegalStateException: No adapter for endpoint  [org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint@1c8b0b1]: 
Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?

我的 Web 服务接线是

<bean id="imageRepository"
    class="org.springframework.ws.samples.mtom.service.StubImageRepository" />

<!-- JMS WIRING TO WS START -->
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />

<bean id="messageDispatcher"
    class="org.springframework.ws.soap.server.SoapMessageDispatcher">
    <property name="endpointMappings">
        <bean
            class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
            <property name="defaultEndpoint">
                <bean
                    class="org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint">
                    <constructor-arg ref="imageRepository" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

<bean
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsConnectionFactory" />
    <property name="destinationName" value="WS.JMS.EXAMPLE.V1.IMAGE.REPO.REQUEST" />
    <property name="messageListener">
        <bean
            class="org.springframework.ws.transport.jms.WebServiceMessageListener">
            <property name="messageFactory" ref="messageFactory" />
            <property name="messageReceiver" ref="messageDispatcher" />
        </bean>
    </property>
</bean>

我的终点代码是

@PayloadRoot(localPart = "StoreImageRequest", namespace = "http://www.springframework.org/spring-ws/samples/mtom")
@ResponsePayload
public String  store(@RequestPayload JAXBElement<Image> requestElement) throws IOException {
    Image request = requestElement.getValue();
    return imageRepository.storeImage(request.getName());
}

我的架构是

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.springframework.org/spring-ws/samples/mtom"
    xmlns:tns="http://www.springframework.org/spring-ws/samples/mtom"
    xmlns:xmime="http://www.w3.org/2005/05/xmlmime" elementFormDefault="qualified">
    <element name="StoreImageRequest" type="tns:Image"/>
    <element name="LoadImageRequest" type="string"/>
    <element name="LoadImageResponse" type="tns:Image"/>
    <complexType name="Image">
        <sequence>
            <element name="name" type="string"/>
        </sequence>
    </complexType>
</schema>

我的客户请求是

<ns2:StoreImageRequest xmlns:ns2="http://www.springframework.org/spring-ws/samples/mtom"><ns2:name>spring-ws-logo.png</ns2:name></ns2:StoreImageRequest>

有人可以帮忙吗?

4

9 回答 9

80

我有一个类似的错误信息。我的问题出在我从 XSD 生成的请求和响应类中。它错过了@XMLRootElement 注释。这导致操作描述(在 WSDL 中)和已实现方法的描述(在 Endpoint 中)不匹配。将 JAXBElement 添加到我的端点方法解决了我的问题。

import javax.xml.bind.JAXBElement;

@PayloadRoot(namespace = "http://foo.bar/books", localPart = "GetBook")
@ResponsePayload
public JAXBElement<MyReponse> getBook(@RequestPayload JAXBElement<MyRequest> myRequest) {
    ...

有关更多详细信息,请参阅此博客:spring-ws:端点没有适配器

于 2014-03-06T14:54:03.883 回答
7

我正在使用 WSDL 文件并按照以下方式进行操作,然后它就起作用了。

  @PayloadRoot(namespace = "http://www.myservice/v1.0/query", localPart = "queryRequest")
  @ResponsePayload
  public JAXBElement<QueryResponse> queryAddrLocation(@RequestPayload JAXBElement<QueryRequest> queryRequest) {
    System.out.println("Welcome to " + queryRequest);
    return createJaxbElement(new QueryResponse(), QueryResponse.class);
  }

  private <T> JAXBElement<T> createJaxbElement(T object, Class<T> clazz) {
    return new JAXBElement<>(new QName(clazz.getSimpleName()), clazz, object);
  }
于 2019-03-21T02:12:12.880 回答
2

我有一个类似的错误。问题是从 XSD/WSDL 生成的请求和响应错过了 @XMLRootElement 注释。通过将 JAXBElement 添加到端点解决了这个问题。

private static final String NAMESPACE_URI = "<targetNamespace>";

@Autowired
Service   service;

@PayloadRoot ( namespace = Endpoint.NAMESPACE_URI, localPart = "name" )
@ResponsePayload
public JAXBElement < Response > Create ( @RequestPayload JAXBElement < Request> request ) throws Exception
{
ObjectFactory factory = new ObjectFactory ( );
Response response = new Response ( );
Request req = request.getValue ( );

response  = this.service.call( req);

return factory.createResponse ( response );
}
于 2019-11-27T13:24:04.430 回答
1

我不确定您的完整 Endpoint 的外观如何,但该类应该使用注释@Endpoint或者它应该实现MessageHandleror PayloadEndpoint

您可以使用的另一件事是方法签名。Spring-WS 的端点映射非常智能:它尝试将方法签名中的输入和输出类与 WSDL 文件进行映射。你确定一个字符串是@ResponsePayLoad,而不是一个StoreImageResponse

例如,这是我的一个端点的方法签名

@PayloadRoot(
    localPart = "GetHiredCandidatesRequest", 
    namespace = DEFAULT_NAMESPACE
)
@ResponsePayload
public GetHiredCandidatesResponse getCandidates (
    @RequestPayload GetHiredCandidatesRequest getCandidate,
    MessageContext messageContext) {
    ...
}

在我的 WSDL 中定义如下:

<wsdl:operation name="GetHiredCandidates">
    <wsdl:input message="tns:GetHiredCandidatesRequest" name="GetHiredCandidatesRequest"></wsdl:input>
    <wsdl:output message="tns:GetHiredCandidatesResponse" name="GetHiredCandidatesResponse"></wsdl:output>
</wsdl:operation>

你看到它是如何映射的吗?也许您在签名中遗漏了类似的内容。

于 2013-01-23T09:55:23.667 回答
1

从 SOAPUI 调用此方法时有效:

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getOrderDetail")
public @ResponsePayload JAXBElement<OrderDetailResponse> getOrderDetail(@RequestPayload JAXBElement<String> customerId, @RequestPayload JAXBElement<String> promoCode)

在下面的方法中,customerStatusRequest 中的值是 null,即使我从 SOAPUI 填充它们。

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCustomerStatus")
public @ResponsePayload
JAXBElement<CustomerStatusResponse> getCustomerStatus(@RequestPayload JAXBElement<CustomerStatusRequest> customerStatusRequest)

(CustomerStatusRequest 实现 Serializable)

看来字符串参数值正在通过调用。但不是自定义类。我以这种方式注释了 CustomerStatusRequest 类:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomerStatusRequest", propOrder = {
    "customerId",
    "gender",
    "dob",
    "lastName",
    "sourceSystemId"
},namespace="http://www.mycompany.com/webservices")

以及 CustomerStatusRequest 中的每个字段:

@XmlElement(name = "customerId", required = true, nillable = true)

该方法被调用,但 customerId 等的值仍然为 null。自定义类是否需要额外的注释?

- 谢谢

于 2019-10-18T14:24:40.047 回答
0

首先,根据指南,应该有一个Endpoint

@Endpoint
public class EmpEndpoint {

    @Autowired
    private EmpService empService;

    //This is like @RequestMapping of Spring MVC    
    @PayloadRoot(localPart = "EmpServiceRequest", namespace = "http://www.example.org/")
    @ResponsePayload
    public EmpServiceResponse getemployeeDetails(@RequestPayload EmpServiceRequest request) {
        EmpServiceResponse response = new ObjectFactory().createEmpServiceResponse();
        List<Employee> l = empService.getemployeeDetails(request.getName());
        response.setName(l.get(0).getName());
        response.setEmail(l.get(0).getEmail());
        return response;
    }
}

还有一个服务及其 实现类,它将具有PayloadRoot和其他注释(请求和响应)

并将其放在您的 spring-servlet.xml 中

  <!-- To detect @Endpoint -->
<sws:annotation-driven/>

<!-- To detect @Service, @Component etc -->
<context:component-scan base-package="your package for eg com.employee" />
于 2013-02-14T10:12:47.473 回答
0

我有同样的错误,但只运行我的 Spring Web Service 集成测试。

问题是,Jaxb2Marshaller如果与Jaxb2Marshaller测试内部相比,我设置了不同的配置。我没有为应用程序和测试使用相同的 Bean。

Jaxb2Marshaller正在运行的应用程序是:

private Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setContextPath("com.company.application");
    marshaller.setMtomEnabled(true);
    return marshaller;
}

但在我的测试中,我使用的是:

@Before
public void init() throws Exception {
    marshaller.setPackagesToScan(ClassUtils.getPackageName(Order.class));
    marshaller.afterPropertiesSet();
}

为了使测试工作,我刚刚定义了两个缺失的属性:

@Before
public void init() throws Exception {
    marshaller.setPackagesToScan(ClassUtils.getPackageName(Order.class));
    marshaller.afterPropertiesSet();
    marshaller.setContextPath("com.company.application");
    marshaller.setMtomEnabled(true);
}
于 2019-06-05T21:03:41.817 回答
0

我在 beanXml 文件中添加了属性

这是工作。

<bean id="marshaller"
    class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
     <property name="supportJaxbElementClass" value = "true"/>
    <property name="contextPaths">
        <list>
            <value>com.xxx</value>
        </list>
    </property>
    <property name="schemas">
        <list>
            <value>classpath:/xsd/service.xsd</value>
        </list>
    </property>
</bean>
于 2021-05-23T00:00:09.460 回答
0

同样的问题,但在我的情况下是因为我忘记放置注释@ResponsePayload@RequestPayload处理函数。只需检查一下!这可能就是它所需要的。

于 2017-04-12T18:51:10.197 回答