当前位置: 首页 > 知识库问答 >
问题:

使用Camel生成肥皂请求

王高邈
2023-03-14

我想使用 wsdl 文件从 Camel 调用第三方网络服务,而无需生成任何客户端代码(因为我认为如果我提供 wsdl 文件,那么 Camel 能够生成我们之前生成的客户端,并且在我们的旧代码中工作)

经过长时间的搜索,我找到了一些帮助我实现目标的代码

代码为

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.dataformat.soap.Soap11DataFormatAdapter;
import org.apache.camel.dataformat.soap.Soap12DataFormatAdapter;
import org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.dataformat.SoapJaxbDataFormat;

import com.camel.model.Application;
public class TestMain {
    static CamelContext context;

    public static void main(String args[]) throws Exception {
        CamelContext context = new DefaultCamelContext();
        ProducerTemplate template = context.createProducerTemplate(0);
        context.start();
        String url="cxf://http://localhost:8081/buzzor-service/services/ApplicationService?" +
          "wsdlURL=http://localhost:8081/buzzor-service/services/ApplicationService?wsdl&" +
          "serviceName={http://service.application.buzzor.atpl.com}ApplicationService&" +
          "portName={http://service.application.buzzor.atpl.com}ApplicationServiceHttpPort&" +
          "dataFormat=MESSAGE";
        Exchange reply = sendSimpleMessage(template, url);
        org.apache.camel.Message out = reply.getOut();
        String result = out.getBody(String.class);

        System.out.println(result);
        Thread.sleep(10000);
        context.stop();
    }

    private static Exchange sendSimpleMessage(ProducerTemplate template,
            String endpointUri) {


        Exchange exchange = template.request(endpointUri, new Processor() {
            public void process(final Exchange exchange) throws Exception {

                exchange.getIn().setBody("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                         + "<soap:Body><ns1:getApplication xmlns:ns1=\"http://cxf.component.camel.apache.org/\">"
//                         + "<arg0 xmlns=\"http://cxf.component.camel.apache.org/\">hello world</arg0>"
                         + "</ns1:getApplication></soap:Body></soap:Envelope>");


                 System.out.println(exchange.getIn().getBody());
            }
        });
        return exchange;
    }
}

这工作正常,但这里我是手动生成soap信封

wsdl文件是

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://service.application.buzzor.atpl.com" xmlns:ns1="urn:http://model.application.buzzor.atpl.com" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:tns="http://service.application.buzzor.atpl.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://service.application.buzzor.atpl.com">
<xsd:element name="getApplication">
<xsd:complexType/>
</xsd:element>
<xsd:element name="getApplicationResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="addApplication">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="ns1:Application"/>
<xsd:element maxOccurs="1" minOccurs="1" name="in1" nillable="true" type="ns1:User"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="addApplicationResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="ns1:ApplicationResult"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="urn:http://model.application.buzzor.atpl.com">
<xsd:complexType name="Application">
<xsd:sequence>
<xsd:element minOccurs="0" name="APP_ID" nillable="true" type="xsd:int"/>
<xsd:element minOccurs="0" name="APP_NAME" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="APP_PASSWORD" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="APP_TYPE" nillable="true" type="xsd:int"/>
<xsd:element minOccurs="0" name="APP_VERSION" nillable="true" type="xsd:int"/>
<xsd:element minOccurs="0" name="EXCEPTION_HANDLED" nillable="true" type="xsd:int"/>
<xsd:element minOccurs="0" name="IS_LOGIN_REQUIRED" nillable="true" type="xsd:int"/>
<xsd:element minOccurs="0" name="LONG_CODES" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="PREVIOUS_NODE_KEY" nillable="true" type="xsd:int"/>
<xsd:element minOccurs="0" name="REPLY_TEXT" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="WELCOME_NOTE" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="User">
<xsd:sequence>
<xsd:element minOccurs="0" name="ACTIVE_STATUS" type="xsd:int"/>
<xsd:element minOccurs="0" name="CUSTOMER_ID" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="FIRST_NAME" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="IS_ADMIN" type="xsd:int"/>
<xsd:element minOccurs="0" name="LAST_NAME" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="LOGIN_USER_ID" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="LOGIN_ALLSC" type="xsd:int"/>
<xsd:element minOccurs="0" name="USER_ACTION" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="USER_CONFIRM_PASSWORD" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="USER_ID" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="USER_PASSWORD" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="USER_PATH" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="USER_STATUS" type="xsd:int"/>
<xsd:element minOccurs="0" name="USER_TYPE" type="xsd:boolean"/>
<xsd:element minOccurs="0" name="VERSION_ID" type="xsd:double"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ApplicationResult">
<xsd:sequence>
<xsd:element minOccurs="0" name="APP_ID" nillable="true" type="xsd:int"/>
<xsd:element minOccurs="0" name="APP_NAME" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="ERROR_MESSAGE" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="ERROR_STATUS" nillable="true" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
  </wsdl:types>
  <wsdl:message name="addApplicationRequest">
    <wsdl:part name="parameters" element="tns:addApplication">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="addApplicationResponse">
    <wsdl:part name="parameters" element="tns:addApplicationResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getApplicationResponse">
    <wsdl:part name="parameters" element="tns:getApplicationResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getApplicationRequest">
    <wsdl:part name="parameters" element="tns:getApplication">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="ApplicationServicePortType">
    <wsdl:operation name="getApplication">
      <wsdl:input name="getApplicationRequest" message="tns:getApplicationRequest">
    </wsdl:input>
      <wsdl:output name="getApplicationResponse" message="tns:getApplicationResponse">
    </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="addApplication">
      <wsdl:input name="addApplicationRequest" message="tns:addApplicationRequest">
    </wsdl:input>
      <wsdl:output name="addApplicationResponse" message="tns:addApplicationResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ApplicationServiceHttpBinding" type="tns:ApplicationServicePortType">
    <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getApplication">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getApplicationRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getApplicationResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="addApplication">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="addApplicationRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="addApplicationResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ApplicationService">
    <wsdl:port name="ApplicationServiceHttpPort" binding="tns:ApplicationServiceHttpBinding">
      <wsdlsoap:address location="http://localhost:8081/buzzor-service/services/ApplicationService"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

现在我想生成肥皂请求,而不是静态的

请帮助我

先谢谢了

共有3个答案

於英朗
2023-03-14

1)让我将您的wsdl文件称为buzzor.wsdl。将您的wsdl保存在您的项目目录中,如下所示,然后使用wsdl2java插件从wsdl文件生成类。在pom.xml中添加以下内容。

<build>
<plugins>
    <plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
                <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
                <wsdlOptions>
                    <wsdlOption>
                        <wsdl>${project.basedir}/src/main/resources/wsdl/buzzor.wsdl</wsdl>
                        <wsdlLocation>classpath:wsdl/buzzor.wsdl</wsdlLocation>
                         <extraargs>
                          <!--this will generate client for you-->
                            <extraarg>-client</extraarg>
                        </extraargs>
                   </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
        </execution>
    </executions>
</plugin>
</plugins>
</build> 

ApplicationServicePortType_ApplicationServiceHttpPort_Client.java 是一个示例客户端,如果需要,可以使用它编写自定义客户端。

在您的情况下,让我们使用 ApplicationServicePortType.java它定义了 2 个方法

a) public java.lang.String getApplication();
b) public http.model_application_buzzor_atpl.ApplicationResult addApplication(...);

2)在您的spring上下文中配置Jaxws客户端。

<beans xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <jaxws:client id="applicationService" serviceClass="com.atpl.buzzor.application.service.ApplicationServicePortType" address="http://localhost:8081/buzzor-service/services/ApplicationService" />

3)在你的骆驼路线中,你可以调用一个豆子…

@Inject
private SoapUtils soapUtils;
...
from("direct:some-endpoint")
.bean(soapUtils,"invokeWebserviceAndGetResponse")

4)在SoapUtils类中,您可以注入applicationService bean并调用webservice

import com.atpl.buzzor.application.service.ApplicationServicePortType;
import http.model_application_buzzor_atpl.ApplicationResult;
import http.model_application_buzzor_atpl.Application;
import http.model_application_buzzor_atpl.User;
public class SoapUtils {
    @Inject
    private ApplicationServicePortType applicationService;

    public void invokeWebserviceAndGetResponse(Exchange exchange) {
         java.lang.String response = applicationService.getApplication();
         ..or..
         Application application = new Application(); //or whichever way you generate this.
         User user = new User(); //or which ever way u generate this.
         ApplicationResult result = applicationService.addApplication(application,user);
         ...
    }
}
锺功
2023-03-14

如果您使用JAXB实体而不是字符串,您可以使用SOAP数据格式将其列表到SOAP信封中。从那一页…

<route>
  <from uri="direct:start"/>
  <marshal>
     <soapjaxb contentPath="com.example.customerservice" version="1.2" elementNameStrategyRef="myNameStrategy"/>
  </marshal>
  <to uri="jms:myQueue"/>
</route>

一般来说,手写XML是不明智的,因为它很容易出错,而且你不能利用这些便利的特性。您还会发现很难对普通字符串使用除XPath之外的任何表达式语言。

璩涛
2023-03-14

我更改了我的代码,现在它工作正常,但我认为我没有正确使用骆驼

因此,请帮助我改进使用camel生成soap请求,而无需编写任何java代码。

package com.camel.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.cxf.DefaultCxfBinding;
import org.apache.camel.component.cxf.common.message.CxfConstants;
import org.apache.camel.impl.DefaultCamelContext;

public class CamelViralTest {
    static CamelContext context;

    public static void main(String args[]) throws Exception {
        CamelContext context = new DefaultCamelContext();
        ProducerTemplate template = context.createProducerTemplate(0);

        context.start();
        String url = "cxf://http://localhost:8081/buzzor-service/services/ApplicationService?"
                + "wsdlURL=http://localhost:8081/buzzor-service/services/ApplicationService?wsdl&"
                + "serviceName={http://service.application.buzzor.atpl.com}ApplicationService&"
                + "portName={http://service.application.buzzor.atpl.com}ApplicationServiceHttpPort"
        +"&dataFormat=MESSAGE";
        Exchange e=sendSimpleMessage1(template,url);
        System.out.println(e.getOut().getBody());
        Thread.sleep(10000);
        context.stop();
    }

    private static Exchange sendSimpleMessage1(ProducerTemplate template,
            String endpointUri) {

        final List<String> params = new ArrayList<String>();
        Map<String, Object> headers = new HashMap<String, Object>();
        headers.put(CxfConstants.OPERATION_NAME, "getApplication");
        headers.put("requestObject", new DefaultCxfBinding());
        params.add("hello world");

        Exchange exchange = template.request(endpointUri, new Processor() {
            public void process(final Exchange exchange) throws Exception {
                SOAPMessage soapMessage=createSOAPRequest();
                exchange.getIn()
                        .setBody(  soapMessage.getSOAPBody());
            }
        });
        return exchange;

    }

    private static SOAPMessage createSOAPRequest() throws Exception {
         MessageFactory messageFactory = MessageFactory.newInstance();
            SOAPMessage soapMessage = messageFactory.createMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();

            String serverURI = "http://ws.cdyne.com/";

            // SOAP Envelope
            SOAPEnvelope envelope = soapPart.getEnvelope();
            envelope.addNamespaceDeclaration("example", serverURI);

            javax.xml.soap.SOAPBody soapBody = envelope.getBody();
            SOAPElement soapBodyElem = soapBody.addChildElement("getApplication", "example");
           /* SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("data", "example");
            soapBodyElem1.addTextNode("mutantninja@gmail.com");*/
            MimeHeaders headers = soapMessage.getMimeHeaders();
            headers.addHeader("SOAPAction", serverURI  + "getApplication");

            soapMessage.saveChanges();

            /* Print the request message */
            System.out.print("Request SOAP Message = ");
            soapMessage.writeTo(System.out);
            System.out.println();

            return soapMessage;
    }
}
 类似资料:
  • SOAP请求有一个服务endpoint和一个xsd文件。但是,没有wsdl文件。我如何从这里手动生成soap请求(作为字符串的xml请求)并将其发送到服务endpoint? 我在SO上找到了类似的答案。但这是针对C#和. NET的,任何针对Java的想法都会受到高度赞赏。

  • 我正在使用CamelCXFendpoint连接到我的soap服务器。我想为客户端的请求添加超时。我正在为此使用continuationTimeout选项。但它不起作用。请求超时,而不等待我配置的时间。 下面是我的endpoint配置。

  • 我在CentOS机器上启用标题中提到的模块时遇到了一些问题。 百胜安装php-mCrypt/php-soc/php-mysql工作正常,并提到它们已经安装,重新启动Apache后,似乎它们没有启用。 例如,我无法定位mcrypt.so,运行php--ini会给出: 这是在我放置extension=mcrypt之后。所以在php中。伊尼。

  • 我很难理解为什么左边的代码生成肥皂请求不起作用,但是如果我调整它到右边的内容,那么它就起作用了? 我添加了到我的java项目: 请注意,在上面没有前缀wsse的图片中,它不起作用。 我可以强制为 强制代码在中生成命名空间,而不是在部分中

  • 问题内容: 尝试指定自定义的肥皂标题。不知道如何填充SoapEnvelope.headerOut属性。 到目前为止我的代码? 这是标题WSDL提取… 问题答案: headerOut是您需要构建的Element []。 像这样 然后将其添加到数组中。

  • 我正在使用CXF Web客户端调用Soap Web服务。 WSDL2JAVA用于从wsdl生成Java代码。有来自soap头的信息,但生成的代码没有访问该头的方法。 如何通过CXF Web客户端获取标题信息?