zoukankan      html  css  js  c++  java
  • 详解WebService开发中四个常见问题(1)

    详解WebService开发中四个常见问题(1)

     

    WebService开发中经常会碰到诸如WebService与方法重载、循环引用、数据被穿该等等问题。本文会给大家一些很好的解决方法。

    AD:WOT2014:用户标签系统与用户数据化运营培训专场

    任何问题都需要从它的根源说起,所以简单说一下WebService的工作原理。客户端调用一个WebService的方法,首先需要将方法名和需要传递的参数包装成XML(也就是SOAP包),通常是通过HTTP传递到服务器端,然后服务器端解析这段XML,得到被调用方法名称和传递来的参数,进而调用WebService实例的相应方法。方法执行完成之后,将返回的结果再包装成XML(SOAP响应)发送到客户端,客户端解析这段XML,进而得到返回结果。这里关键的地方在于中间加入了对象和XML相互转换的过程。

    问题一:WebService与方法重载

    首先说明,WebService不支持方法重载。下面举例说明。

    例如定义如下WebService接口:

    1 @WebService
    2 public interface IHello {
    3         @WebMethod
    4         public String sayHello(int id);
    5
    6         @WebMethod
    7         public String sayHello(String name);
    8        
    9         @WebMethod
    10         public String sayHello2(int id);
    11
    12         @WebMethod
    13         public String sayHello2(int id, String name);
    14     }

    先来看方法sayHello(),如果客户端发送如下SOAP请求:

    1 <soap:Envelope>
    2         <soap:Body>
    3             <sayHello>
    4                 <arg0>11</arg0>
    5             </sayHello>
    6         </soap:Body>
    7     </soap:Envelope>

    从SOAP请求我们可以看出客户端需要调用方法为sayHello(),所传递的参数为11,但是无法知道是整数的11,还是字符串"11",所以也就无法确定所调用的方法是哪一个。

    接下来看一下sayHello2(),如果客户端传递的参数只包括一个id值,例如:

    1 <soap:Envelope>
    2         <soap:Body>
    3             <sayHello2>
    4                 <arg0>1</arg0>
    5             </sayHello2>
    6         </soap:Body>
    7     </soap:Envelope>

    还是无法判断调用的是哪个方法,因为可以理解为客户端传递的第二个参数为空(Null)。

    通常情况下,在发布一个含有重载方法的WebService时会有异常发生,或者当调用一个方法时,服务器端报告找不到相对应的方法。

    问题二:我的数据被修改了?

    先来看WebService接口:

    1 @WebService
    2     public interface IHello {
    3    
    4         @WebMethod
    5         public String sayHello(IPerson person);
    6    
    7     }
    8    
    9     public interface IPerson {
    10         ...
    11     }
    12    
    13     public class Person implements IPerson{
    14         ...
    15     }

    这里需要注意的是WebService的方法sayHello()的参数是一个接口,而不是一个具体类(例如Aegis绑定就允许直接发布这样的WebService)。在客户端调用sayHello()的时候传递一个Person对象,它实现了IPerson接口。经过中间一系列的XML和对象之间的转换过程,服务器端得到的只是一个实现了IPerson接口的实例,它不一定就是一个Person对象,如果要强制将其转换为Person,就有可能抛出异常。

    问题的根源在于Aegis将XML转换为Java对象是通过Proxy或CGlib这类的工具生成一个“代理类”实现IPerson接口,然后创建这个代理类的一个实例,那它肯定不是一个Person了。

  • 相关阅读:
    mac上配置apidoc环境
    Yii 2.0 GII 访问404错误
    yii框架下使用redis
    PHPEXCEL读出数据是PHPExcel_RichText类型
    php实现仿百度分页
    apache的.htaccess文件作用和相关配置
    Yii2.0 解决“the requested URL was not found on this server”问题
    [基础与理论]C#变量
    基础&理论]C#的基本语法
    [基础&理论]C#的含义
  • 原文地址:https://www.cnblogs.com/L-H-R-X-hehe/p/3815455.html
Copyright © 2011-2022 走看看