【问题标题】:Java, apache.CXF plugin - Using local WSDL to consume remotely hosted servicesJava, apache.CXF plugin - 使用本地 WSDL 使用远程托管服务
【发布时间】:2022-01-20 08:07:31
【问题描述】:

Soap 服务是远程托管的,但由于我们服务器的一些限制,我获得了 WSDL 并将其存储在本地。使用 maven、org.apache.cxf 插件和生成源命令我从本地 WSDL 生成了类。

WebServiceClient 类属性:

@WebServiceClient(name = "ManageCredit",
                  wsdlLocation = localWSDLAddress,
                  targetNamespace = targetNamespace)
public class ManageCredit extends Service {
    public final static URL WSDL_LOCATION;

    public final static QName SERVICE = new QName(targetNamespace, "ManageCredit");
    public final static QName ManageCreditEndpoint = new QName(targetNamespace, "ManageCreditEndpoint");
    static {
        URL url = null;
        try {
            url = new URL(localWSDLAddress);
        } catch (MalformedURLException e) {
            java.util.logging.Logger.getLogger(ManageCredit.class.getName())
                .log(java.util.logging.Level.INFO,
                     "Can not initialize the default wsdl from {0}", localWSDLAddress);
        }
        WSDL_LOCATION = url;
    }

客户端设置:

ManageCredit manageCreditService = new ManageCredit();
ManageCreditPortType manageCreditPortType = manageCreditService.getManageCreditEndpoint();
SignContractRequest signContractRequest = new SignContractRequest();
signContractRequest.setRequestID("123");
signContractRequest.setApplicationID("1111");
signContractRequest.setChannelID("someValue");
manageCreditPortType.signContract(signContractRequest);

使用此代码,调用 http://localhost:8080/.... 我需要调用远程服务器,例如https://example.google:1820,而不是本地主机。如何在不更改 wsdl 位置的情况下更改客户端调用的端点。

【问题讨论】:

    标签: java maven wsdl cxf soap-client


    【解决方案1】:

    由于您在本地下载了 WSDL,因此您现在可以控制它。因此,如果您将 WSDL 文件本身中的 SOAP 地址更改为指向您想从客户端调用的任何地址,它可能会起作用。

    或者,您可以尝试使用BindingProvider.ENDPOINT_ADDRESS_PROPERTY,如here 所示,尽管据我记得您需要为每个请求执行此操作,而不是为整个服务客户端配置它:

    MyService service = new MyService(wsdlURL, serviceName);
    ServicePort client = service.getServicePort();
    BindingProvider provider = (BindingProvider)client;
    // You can set the address per request here
    provider.getRequestContext().put(
         BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
         "http://my/new/url/to/the/service");
    

    【讨论】:

      【解决方案2】:

      您应该将 wsdl 文件复制到 src/main/resources 文件夹下的某个位置,以便将其打包到项目的 jar 文件中(对于下面的示例,我使用 src/main/resources/META-INF/wsdl)。配置cxf-codegen-plugin时,指定wsdlLocation配置值,如下图。

      <plugin>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-codegen-plugin</artifactId>
        <version>3.3.0</version>
        <executions>
          <execution>
            <id>my-wsdl</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>wsdl2java</goal>
            </goals>
            <configuration>
              <encoding>UTF-8</encoding>
              <wsdlOptions>
                <wsdlOption>
                  <wsdl>${project.basedir}\src\main\resources\META-INF\wsdl\helloWorld.wsdl</wsdl>
                  <wsdlLocation>classpath:/META-INF/wsdl/helloWorld.wsdl</wsdlLocation>
                </wsdlOption>
              </wsdlOptions>
            </configuration>
          </execution>
        </executions>
      </plugin>
      

      然后您生成的 WebServiceClient 代码应该从类路径加载 wsdl,类似于此...

      @WebServiceClient(name = "HelloWorldService",
                        wsdlLocation = "classpath:/META-INF/wsdl/helloWorld.wsdl",
                        targetNamespace = "http://example.com/helloWorld")
      public class HelloWorldService extends Service {
      
          public final static URL WSDL_LOCATION;
      
          public final static QName SERVICE = new QName("http://example.com/helloWorld", "HelloWorldService");
          public final static QName HelloWorldProxyPort = new QName("http://example.com/helloWorld", "HelloWorldProxyPort");
          static {
              URL url = HelloWorldService.class.getClassLoader().getResource("/META-INF/wsdl/helloWorld.wsdl");
              if (url == null) {
                  url = HelloWorldService.class.getClassLoader().getResource("META-INF/wsdl/helloWorld.wsdl");
              }
              if (url == null) {
                  java.util.logging.Logger.getLogger(HelloWorldService.class.getName())
                      .log(java.util.logging.Level.INFO,
                           "Can not initialize the default wsdl from {0}", "classpath:/META-INF/wsdl/helloWorld.wsdl");
              }
              WSDL_LOCATION = url;
          }
      
          ...
      }
      

      使用服务时,可以为服务设置端点地址如下...

      HelloWorldService helloWorldService = new HelloWorldService();
      HelloWorldPort client = service.getHelloWorldPort();
      BindingProvider provider = (BindingProvider)client;
      // You can set the address per request here
      provider.getRequestContext().put(
           BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
           "http://my/new/url/to/the/service");
      

      【讨论】:

      • 谢谢。那行得通
      • 你能把它标记为接受的答案吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      • 2010-12-01
      • 2017-08-25
      • 1970-01-01
      相关资源
      最近更新 更多