WebService开发中经常会碰到诸如WebService与方法重载、循环引用、数据被穿该等等问题。本文会给大家一些很好的解决方法。
任何问题都需求从它的本源说起,所以简单说一下WebService的作业原理。客户端调用一个WebService的办法,首要需求将办法名和需求传递的参数包装成XML(也便是SOAP包),通常是通过HTTP传递到服务器端,然后服务器端解析这段XML,得到被调用办法称号和传递来的参数,然后调用WebService实例的相应办法。办法履行完结之后,将回来的成果再包装成XML(SOAP呼应)发送到客户端,客户端解析这段XML,然后得到回来成果。这儿要害的当地在于中心加入了目标和XML彼此转化的进程。
问题一:WebService与办法重载
首要阐明,WebService不支持办法重载。下面举例阐明。
例如界说如下WebService接口:
1 @WebService |
先来看办法sayHello(),假如客户端发送如下SOAP恳求:
1 <soap:Envelope> |
从SOAP恳求咱们能够看出客户端需求调用办法为sayHello(),所传递的参数为11,可是无法知道是整数的11,仍是字符串"11",所以也就无法确认所调用的办法是哪一个。
接下来看一下sayHello2(),假如客户端传递的参数只包括一个id值,例如:
1 <soap:Envelope> |
仍是无法判别调用的是哪个办法,由于能够理解为客户端传递的第二个参数为空(Null)。
通常情况下,在发布一个含有重载办法的WebService时会有反常产生,或许当调用一个办法时,服务器端陈述找不到相对应的办法。
问题二:我的数据被修改了?
先来看WebService接口:
1 @WebService |
这儿需求留意的是WebService的办法sayHello()的参数是一个接口,而不是一个具体类(例如Aegis绑定就答应直接发布这样的WebService)。在客户端调用sayHello()的时分传递一个Person目标,它完成了IPerson接口。通过中心一系列的XML和目标之间的转化进程,服务器端得到的仅仅一个完成了IPerson接口的实例,它不必定便是一个Person目标,假如要强制将其转化为Person,就有或许抛出反常。
问题的本源在于Aegis将XML转化为Java目标是通过Proxy或CGlib这类的东西生成一个“署理类”完成IPerson接口,然后创立这个署理类的一个实例,那它必定不是一个Person了。
#p#
问题三:循环引证
仍是先来看一个比如。下面是WebService的接口:
1 @WebService |
请留意,Teacher和Student是一对多的“双向”联系。在这种情况下,咱们能够想一下如何将一个Teacher目标转化成一段XML?
您或许想到下面的答案:
1 <teacher> |
看到了吧,XML居然也会进入“死循环”。问题的本源在于目标之间的循环引证。这种问题通常在客户端发送WebService恳求之前就会抛出反常,由于无法将这个目标转化为可传输的XML。
问题四:庞然大物
仍是先看一个比如,下面是WebService的接口:
1 @WebService |
这个办法接纳一个Student数组,包括成百上千个Student,与上面比如不同的是Student和Teacher现在是多对一的单向联系,所以不会有“循环引证”的问题。假定所有这些Student的Teacher是一个人。咱们试着将这个Student数组目标转化为一段XML,如下:
1 <student> |
问题出来了,看到了没有,每个Student节点下面都有一个Teacher节点,当这段XML被接纳方转化为Student数组时,每个学生都有了一个自己的教师,Teacher目标被仿制了成百上千次,通过这么一个转化--传输--转化的进程,这个数组目标真的成了一个“庞然大物”。
问题的本源在于Student和Teacher之间的联系是多对一,当传送“多”方时,“一”方有或许会被仿制屡次。然后占用很多网络传输带宽和内存。在这儿参数不必定非要是一个调集或许数组,例如ObjectA和ObjectB都有一个对ObjectC的引证,通过SOAP传送往后,ObjectC就由一个变成两个了,别离归于ObjectA和ObjectB,而不再是同享一个ObjectC了。
【修改引荐】
- XML WebService彻底实例具体解析
- XML新手入门 创立结构杰出的XML
- 完成XML和Web服务时要防止的三种常见过错