没有端点适配器;您的端点是使用@Endpoint注释的,还是实现了MessageHandler或PayloadEndpoint等受支持的接口?

时间:2013-01-18 00:13:38

标签: java jms spring-ws

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

有人能帮忙吗?

8 个答案:

答案 0 :(得分:48)

我有类似的错误消息。我的问题出在我从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

答案 1 :(得分:0)

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

你可以玩的其他东西是方法签名。 Spring-WS'端点映射非常智能:它尝试使用WSDL文件映射方法签名中的输入和输出类。你确定String是@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 :(得分:0)

首先,根据指南,应该有端点

@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" />

答案 3 :(得分:0)

同样的问题,但在我的情况下是因为我忘了在注册表函数中放置注释 #include <iostream> #include<cstdlib> #include<iomanip> #include <ctime> using namespace std; void displayTable(int table[10][3]); bool testMe(int testTable[10][3]); void createTables(int testTable[10][3], int ansTable[10][3], int usersChoice); bool AllAnswersAreTested(bool tested[10]); void gradeMe(int testTable[10][3], int ansTable[10][3]); void displayMenu(); int main() { srand(time(NULL)); int userInput = 0; int tableChoice = 0; int myTable[10][3] = {0}; int testTable[10][3]; int ansTable[10][3]; bool tested = false; do { displayMenu(); //Display the menu of choices cin >> userInput; cout << endl; switch (userInput) //Validate menu choices 1-4 { case 1: //Display a users choice of table displayTable(myTable); break; case 2: //Test user on users choice of table cout << "What times table test would you like to take? > "; cin >> tableChoice; createTables(testTable, ansTable, tableChoice); tested = testMe(testTable); if (tested) { gradeMe(testTable, ansTable); } break; case 3: //Display a new table of the users choice displayTable(myTable); break; case 4: //Quit program menu option cout << "Program ending.\n"; return 0; default: //Invalid entry cout << "You entered an invalid item number. Please enter a number from 1 to 4.\n"; cout << endl; } } while (userInput != 4); return 0; } void displayTable(int myTable[10][3]) { int num; //initialize local variables //Ask the user what times table they would like to review cout << "What times table would you like to review?" << endl;; cout << "Please enter a value from 1 to 12 > \n"; cout << "\n"; cin >> num; cout << endl; for (int i = 0; i < 10; i++) { myTable[i][0] = i + 1; myTable[i][1] = num; myTable[i][2] = myTable[i][0] * myTable[i][1]; } for (int i = 0; i < 10; i++) { cout << setw(3)<< myTable[i][0] << " * " << myTable[i][1] << " = " << myTable[i][2] << endl; } cout << endl; } void createTables(int testTable[10][3], int ansTable[10][3], int usersChoice) { for (int i = 0; i < 10; i++) { testTable[i][0] = i + 1; testTable[i][1] = usersChoice; testTable[i][2] = 0; ansTable[i][0] = i + 1; ansTable[i][1] = usersChoice; ansTable[i][2] = usersChoice * (i + 1); } } bool testMe(int testTable[10][3]) { bool tested[10] = { false, false, false, false, false,false, false, false, false, false }; while (!AllAnswersAreTested(tested)) { int index = rand() % 10; if (tested[index] == false) { int randomNum = testTable[index][0]; int tableChoice = testTable[index][1]; int answer; cout << "What is " << randomNum << " X " << tableChoice << " = "; cin >> answer; testTable[index][2] = answer; tested[index] = true; } } return true; } bool AllAnswersAreTested(bool tested[10]) { for (int i = 0; i < 10; i++) { if (tested[i] == false) { return false; } } return true; } void gradeMe(int testTable[10][3], int ansTable[10][3]) { int correctAnswers = 0; for (int i = 0; i<10; i++) { if (testTable[i][2] == ansTable[i][2]) { correctAnswers++; } } int score = (correctAnswers * 10); if (score == 100) { cout << "You passed the test! PERFECT SCORE!!" << endl; cout << endl; } else if (score >= 70) { cout << "You passed the test. Your Score is: "; cout << score; cout << endl; } else if (score < 70) { cout << "You did not pass the test. Your Score is: "; cout << score; cout << endl; } } //Display the menu function void displayMenu() { cout << " Multiplication Tables" << endl; cout << endl; cout << " 1. Review MyTable" << endl; cout << " 2. Test Me" << endl; cout << " 3. Enter a New Multiplication Table (1-12)"; cout << " 4. Quit" << endl; cout << " Enter a Menu Item > "; } @ResponsePayload。检查一下!可能只需要它。

答案 4 :(得分:0)

我正在使用WSDL文件,并按如下所述进行操作,然后它起作用了。

first time 2
second time 2

答案 5 :(得分: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);
}

答案 6 :(得分:0)

从SOAPUI调用时,此方法有效:

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

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

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

(CustomerStatusRequest实现序列化)

似乎String参数值正在通过调用完成。但不是自定义类。 我以这种方式注释了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。自定义类是否需要其他注释?

-谢谢

答案 7 :(得分:0)

我有一个类似的错误。问题是从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 );
}