相关文章推荐
腹黑的墨镜  ·  cmd | Microsoft Learn·  1 月前    · 
踏实的水煮鱼  ·  java.lang.SecurityExce ...·  8 月前    · 
个性的紫菜汤  ·  gitkraken破解版-掘金·  1 年前    · 
玉树临风的茶壶  ·  Inno Setup 介绍 - ...·  1 年前    · 
C# 调用soap接口时 No binding operation info while invoking unknown method with params unknown 2021-08-04 15:16:18

与其他部门有个常规的 WebService 接口,对方提供服务,这边调用。像往常一样,使用 cxf 生成了客户端的代码并调用,开发的过程中并没有遇到什么问题,测试也没发现问题。然而一个礼拜之后正式上线的生产环境中,客户端调用接口总是抛出异常 服务器发送了 HTTP 状态代码 302: Moved Temporarily

    @Test
    public void test() throws Exception {
        URL url = new URL("https://home.winning.com/web-service/cxf/findReportEntity?wsdl");
        ReportEntityService service = new ReportEntityServiceImplService(url)
                .getReportEntityServiceImplPort();
        ReportEntity res = service.findOne("");
        System.out.println(res.getEnterpirseName());
com.sun.xml.internal.ws.client.ClientTransportException: 服务器发送了 HTTP 状态代码 302: Moved Temporarily
	at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.checkStatusCode(HttpTransportPipe.java:310)
	at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.createResponsePacket(HttpTransportPipe.java:259)
	at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:217)
	at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:130)
	at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:95)
	at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:1121)
	at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:1035)
	at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:1004)
	at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:862)
	at com.sun.xml.internal.ws.client.Stub.process(Stub.java:448)
	at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:178)
	at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
	at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77)
	at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147)
	at com.sun.proxy.$Proxy32.findOne(Unknown Source)
	at SkytechTest.test(SkytechTest.java:30)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)

检查了下配置的 URL 发现,实际配置的地址是HTTPS形式的。因为测试环境与生产环境的配置都是一样的,除了URL,测试环境是直接通过 IP 访问的。基本上可以确定问题就出在HTTPS上了。初步判断,应该是对方在生产环境中使用了 nginx 做了反向代理,并且开启了 SSL,导致访问接口的时候被重定向了。但是,wsdl 是可以通过 https 访问的,这就有些奇怪了。 为了排查问题,用C# 快速写了一个测试程序:

ReportEntityServiceClient client = new ReportEntityServiceClient();
    reportEntity report = client.findOne("");
    Console.WriteLine(report.enterpirseName);
catch (Exception ex)
     Console.WriteLine(ex.Message);

同样抛出了异常,异常消息与 Java 有些不同, No binding operation info while invoking unknown method with params unknown., 将 app.config 文件中的 endpoint address 节点修改为 https, 运行提示:提供的 URI 方案“https”无效,应为“http”。参数名: via 问题可以确定,就是 https 导致的问题。通过 Wireshark 抓包来看,接口调用请求的为 http,虽然配置的 URL 是 https 但是实际上调用的其实是 http。

如果 WebService 调用可以设置代理,把代理地址设置成 https 应该就能解决问题。 经过一番 Google 貌似找到一个解决方法, 通过 BindingProvider 拿到请求上下文,添加 BindingProvider.ENDPOINT_ADDRESS_PROPERTY:

    @Test
    public void test() throws Exception {
        String wsdlLocation = "https://home.winning.com/web-service/cxf/findReportEntity?wsdl";
        URL url = new URL(wsdlLocation);
        ReportEntityService service = new ReportEntityServiceImplService(url)
                .getReportEntityServiceImplPort();
        ((BindingProvider) service).getRequestContext()
                .put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlLocation);
        ReportEntity res = service.findOne("");
        System.out.println(res.getEnterpirseName());

问题就这么解决了,只需要添加一行代码就搞定了。对于 .NET 需要修改 app.config , 在 binding 节点中添加 security 配置,并且将 endpoint address 节点修改为 https。详细配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="ReportEntityServiceImplServiceSoapBinding" >
          <security mode="Transport">
            <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="Certificate" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://home.winning.com/web-service/cxf/findReportEntity"
          binding="basicHttpBinding" bindingConfiguration="ReportEntityServiceImplServiceSoapBinding"
          contract="ServiceReference.ReportEntityService" name="ReportEntityServiceImplPort" />
    </client>
  </system.serviceModel>
</configuration>

BindingProvider 定义了获取 request 与 response 上下文 (context)的方法,context 是一个 Map, 可以设置一些属性。 除了 ENDPOINT_ADDRESS_PROPERTY 以外,还有 USERNAME_PROPERTY 、PASSWORD_PROPERTY 等属性。 参考 Purpose of BindingProvider in JAX-WS web service

2021-01-08 10:43:03.718 WARN 4912 --- [nio-8080-exec-1] o.a.cxf.phase.PhaseInterceptorChain : Interceptor for {http://webservice.leftso.com/}RmsWebServiceImplService has thrown exception, unwinding now org.a. 警告: Interceptor for {http://test.cxf.atguigu.com/}HelloWorldImplService has thrown exception, unwinding now org.apache.cxf.interceptor.Fault: No binding operation info while invoking unknown method with params unknown. at org... 1.1 WebService是什么 ​ WebService是一种跨编程语言和跨操作系统平台的远程调用技术。 ​ Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。 ​ Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换 本人这两天在学WebService.按照教学视频里的教程尝试做了一个最简单的Demo,但出现了一下问题。百思不得其解,在网上找了很久也没有找到答案。故此在这里发帖求各位大神指点下。 下面是问题描述: 照理说能访问到wsdl文件就说明web Service 已发布出去了,定义的接口也能调用SOAP Request Envelope和SOAP Response Envelope应 1. Demo (转载 http://mushme.iteye.com/blog/1776078)cxf的官网文档地址:http://cxf.apache.org/docs/ 1.建立一个web project,名称为cfx-new,部署目录写成ROOT 2.下载最新的cxf包http://cxf.apache.org/download.html,我下载的是apache-cxf-2.5.2.zip... CXF发布webservice之后访问报错: org.apache.cxf.interceptor.Fault: No binding operation info while invoking unknown method with params unknown. at org.apache.cxf.service.invoker.AbstractInvoker.invoke(A...