端点没有适配器;您的端点是不是使用 @Endpoint 进行了注释,或者它是不是实现了受支持的接口,例如 MessageHandler 或 PayloadEndpoint?

Posted

技术标签:

【中文标题】端点没有适配器;您的端点是不是使用 @Endpoint 进行了注释,或者它是不是实现了受支持的接口,例如 MessageHandler 或 PayloadEndpoint?【英文标题】:No adapter for endpoint; Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?端点没有适配器;您的端点是否使用 @Endpoint 进行了注释,或者它是否实现了受支持的接口,例如 MessageHandler 或 PayloadEndpoint? 【发布时间】:2013-01-01 15:57:05 【问题描述】:

我正在努力使用带有 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?

我的网络服务接线是

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

有人可以帮忙吗?

【问题讨论】:

【参考方案1】:

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

你可以玩的另一件事是方法签名。 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>

你看到它是如何映射的吗?也许您的签名中缺少类似的内容。

【讨论】:

【参考方案2】:

首先,根据指南,应该有一个 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;
    

还有一个 Service 及其 implementation 类,该类将具有 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" />

【讨论】:

【参考方案3】:

我收到了类似的错误消息。我的问题出在我从 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: No adapter for endpoint

【讨论】:

谢谢。这可能不是 OP 的问题,但这是我的问题。 也为我工作。这是我的代码示例:code @PayloadRoot(namespace = NAMESPACE_URI, localPart = "ServiceCheckRequest") @ResponsePayload public JAXBElement serviceCheckRequest( @RequestPayload ServiceCheckRequestType request) ServiceCheckResponseType response = new ServiceCheckResponseType(); response.setSystem("测试系统"); QName qname = new QName("ServiceCheckRequest"); JAXBElement jaxbElement = new JAXBElement(qname, ServiceCheckResponseType.class, response);返回 jaxbElement; 我看不出@XMLRootElement 与解决方案有什么关系。我还发现用 JAXBElement 包装我的响应很有帮助,但这似乎不是我应该在像 Spring 这样的简单框架中做的事情。 谢谢,将@XMLRootElement 添加到从 XSD 生成的 JaxB 类对我有用。 感谢一百万,在 JAXBElement 中包装响应为我解决了这个问题。我的例子: QName qname = new QName("ResponseElement"); JAXBElement jaxbElement = new JAXBElement(qname, ResponseElement.class, response);【参考方案4】:

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

【讨论】:

【参考方案5】:

我正在使用 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);
  

【讨论】:

这甚至无法编译。 @VladDinulescu 您必须为 JAXBElment 添加库,并创建 2 个对象:QueryRequest 和 QueryResponse。 Complie在此之后会很好。我从示例中复制的代码已经对我有用了:) 如果你返回一个QueryResponse并且方法的返回类型是JAXBElement,不,它不会编译。 将返回值更新为 JAXBElement。谢谢@VladDinulescu【参考方案6】:

我遇到了同样的错误,但只运行了我的 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);

【讨论】:

【参考方案7】:

从 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 实现可序列化)

似乎字符串参数值正在通过调用。但不是自定义类。 我以这种方式注释了 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。自定义类是否需要额外的注解?

--谢谢

【讨论】:

【参考方案8】:

我遇到了类似的错误。问题是从 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 );

【讨论】:

我已经这样做了,但又给了我一个错误:“在模块路径或类路径上找不到 JAXB-API 的实现。” @VincentGuyard 修复您需要这样做:***.com/a/51916222/912829【参考方案9】:

我在 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>

【讨论】:

以上是关于端点没有适配器;您的端点是不是使用 @Endpoint 进行了注释,或者它是不是实现了受支持的接口,例如 MessageHandler 或 PayloadEndpoint?的主要内容,如果未能解决你的问题,请参考以下文章

MobileFirst 7.1 测试令牌端点中的随机用户 ID

Keycloak - 通过OIDC端点检索JWT令牌

没有 MEX 端点的带有 BasicHttpBinding 的 WCF 服务可以被绝对陌生的人利用吗?

Spring Boot之执行器端点(Actuator Endpoint)实现剖析

WCF 找不到默认端点

使用 RX And​​roid 进行并行 API 调用