我正试图走过Camel Report Incident tutorial,并被困在part 5的末尾。当我尝试运行单元测试时,它失败并显示消息The given SOAPAction http://reportincident.example.camel.apache.org/ReportIncident does not match an operation.
我看到一个similar question问题是WSDL文件中声明的soapAction属性与实际SOAP请求的值不同。这似乎不是我的情况。什么是错误的想法?提前谢谢。
reportIncident.wsdl
<?xml version="1.0" encoding="ISO-8859-1"?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://reportincident.example.camel.apache.org"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://reportincident.example.camel.apache.org">
<!-- Type definitions for input- and output parameters for webservice -->
<wsdl:types>
<xs:schema targetNamespace="http://reportincident.example.camel.apache.org">
<xs:element name="inputReportIncident">
<xs:complexType name="inputReportIncident">
<xs:sequence>
<xs:element type="xs:string" name="incidentId" />
<xs:element type="xs:string" name="incidentDate" />
<xs:element type="xs:string" name="givenName" />
<xs:element type="xs:string" name="familyName" />
<xs:element type="xs:string" name="summary" />
<xs:element type="xs:string" name="details" />
<xs:element type="xs:string" name="email" />
<xs:element type="xs:string" name="phone" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="outputReportIncident">
<xs:complexType name="outputReportIncident">
<xs:sequence>
<xs:element type="xs:string" name="code" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<!-- Message definitions for input and output -->
<wsdl:message name="inputReportIncident">
<wsdl:part name="parameters" element="tns:inputReportIncident" />
</wsdl:message>
<wsdl:message name="outputReportIncident">
<wsdl:part name="parameters" element="tns:outputReportIncident" />
</wsdl:message>
<!-- Port (interface) definitions -->
<wsdl:portType name="ReportIncidentEndpoint">
<wsdl:operation name="ReportIncident">
<wsdl:input message="tns:inputReportIncident" />
<wsdl:output message="tns:outputReportIncident" />
</wsdl:operation>
</wsdl:portType>
<!-- Port bindings to transports and encoding - HTTP, document literal
encoding is used -->
<wsdl:binding name="ReportIncidentBinding" type="tns:ReportIncidentEndpoint">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="ReportIncident">
<soap:operation soapAction="http://reportincident.example.camel.apache.org/ReportIncident" style="document" />
<wsdl:input>
<soap:body parts="parameters" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body parts="parameters" use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- Service definition -->
<wsdl:service name="ReportIncidentService">
<wsdl:port name="ReportIncidentPort" binding="tns:ReportIncidentBinding">
<soap:address location="http://reportincident.example.camel.apache.org" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
路由定义(在RouteBuilder子类中)
OutputReportIncident ok = new OutputReportIncident();
ok.setCode("0");
// endpoint to our CXF webservice
String cxfEndpoint = "cxf://http://localhost:8080/part-five/webservices/incident"
+ "?serviceClass=org.apache.camel.example.reportincident.ReportIncidentEndpoint"
+ "&wsdlURL=reportIncident.wsdl";
// first part from the webservice -> file backup
from(cxfEndpoint)
// we need to convert the CXF payload to InputReportIncident that FilenameGenerator and velocity expects
.convertBodyTo(InputReportIncident.class)
// then set the file name using the FilenameGenerator bean
.setHeader("CamelFileName", BeanLanguage.bean(FilenameGenerator.class, "generateFilename"))
// transform the message using velocity to generate the mail message
.to("velocity:mailBody.vm")
// and store the file
.to("file://target/subfolder")
// return OK as response
// usando transformação!
.transform(constant(ok));
pom.xml (wsdl2java用于从WSDL生成Java文件)
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.13.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/resources/reportIncident.wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
测试代码
package org.apache.camel.example.reportincident;
import static org.junit.Assert.*;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Test;
import org.jvnet.mock_javamail.Mailbox;
public class ReportIncidentRoutesTest {
// should be the same address as we have in our route
private static String ADDRESS = "http://localhost:8080/part-five/webservices/incident";
private CamelContext context;
@Test
public void testRendportIncident() throws Exception {
// start camel
startCamel();
// assert mailbox is empty before starting
Mailbox inbox = Mailbox.get("incident@mycompany.com");
assertEquals("Should not have mails", 0, inbox.size());
// create input parameter
InputReportIncident input = new InputReportIncident();
input.setIncidentId("123");
input.setIncidentDate("2008-08-18");
input.setGivenName("Claus");
input.setFamilyName("Ibsen");
input.setSummary("Bla");
input.setDetails("Bla bla");
input.setEmail("davsclaus@apache.org");
input.setPhone("0045 2962 7576");
// create the webservice client and send the request
ReportIncidentEndpoint client = createCXFClient();
OutputReportIncident out = client.reportIncident(input);
// assert we got a OK back
assertEquals("0", out.getCode());
// let some time pass to allow Camel to pickup the file and send it as an email
Thread.sleep(3000);
// assert mail box
assertEquals("Should have got 1 mail", 1, inbox.size());
// stop camel
context.stop();
}
private void startCamel() throws Exception {
context = new DefaultCamelContext();
context.disableJMX();
context.addRoutes(new ReportIncidentRoutes());
context.start();
}
private ReportIncidentEndpoint createCXFClient() {
// we use CXF to create a client for us as its easier than JAXWS and works
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(ReportIncidentEndpoint.class);
factory.setAddress(ADDRESS);
return (ReportIncidentEndpoint) factory.create();
}
}
答案 0 :(得分:1)
我认为你只需要将WSDL url传递给JaxWsProxyFactoryBean,它就可以为你处理soap动作。
请像这样更改ReportIncidentRoutesTest.createCXFClient()
private ReportIncidentEndpoint createCXFClient() {
// we use CXF to create a client for us as its easier than JAXWS and works
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(ReportIncidentEndpoint.class);
factory.setWsdlURL("reportIncident.wsdl");
factory.setAddress(ADDRESS);
return (ReportIncidentEndpoint) factory.create();
}