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

任何问题都需求从它的本源说起,所以简单说一下WebService的作业原理。客户端调用一个WebService的办法,首要需求将办法名和需求传递的参数包装成XML(也便是SOAP包),通常是通过HTTP传递到服务器端,然后服务器端解析这段XML,得到被调用办法称号和传递来的参数,然后调用WebService实例的相应办法。办法履行完结之后,将回来的成果再包装成XML(SOAP呼应)发送到客户端,客户端解析这段XML,然后得到回来成果。这儿要害的当地在于中心加入了目标和XML彼此转化的进程。

详解WebService开发中四个常见问题(调用webservices出错什么意思)  问题 开发 WebService 第1张

问题一: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了。

#p#

问题三:循环引证

仍是先来看一个比如。下面是WebService的接口:

1 @WebService
2 public interface IHello {
3
4 @WebMethod
5 public String sayHello(Teacher teacher);
6
7 }
8
9 public class Teacher {
10 private Student[] students;
11
12 //getters and setters
13 ...
14 }
15
16 public class Student {
17 private Teacher teacher;
18
19 //getters and setters
20 ...
21 }

请留意,Teacher和Student是一对多的“双向”联系。在这种情况下,咱们能够想一下如何将一个Teacher目标转化成一段XML?

您或许想到下面的答案:

1 <teacher>
2 <students>
3 <teacher>
4 <students>
5 <teacher>
6 <students>
7 ...
8 </students>
9 ...
10 </teacher>
11 </students>
12 ...
13 </teacher>
14 </students>
15
16 <students>
17 ...
18 </students>
19 ...
20 </teacher>

看到了吧,XML居然也会进入“死循环”。问题的本源在于目标之间的循环引证。这种问题通常在客户端发送WebService恳求之前就会抛出反常,由于无法将这个目标转化为可传输的XML。

问题四:庞然大物

仍是先看一个比如,下面是WebService的接口:

1 @WebService
2 public interface IHello {
3
4 @WebMethod
5 public String sayHello(Student[] students);
6
7 }
8
9 public class Teacher {
10 ...
11 }
12
13 public class Student {
14 private Teacher teacher;
15
16 //getters and setters
17 ...
18 }

这个办法接纳一个Student数组,包括成百上千个Student,与上面比如不同的是Student和Teacher现在是多对一的单向联系,所以不会有“循环引证”的问题。假定所有这些Student的Teacher是一个人。咱们试着将这个Student数组目标转化为一段XML,如下:

1 <student>
2 <teacher>
3 ...
4 </teacher>
5 </student>
6 <student>
7 <teacher>
8 ...
9 </teacher>
10 </student>
11 ...

问题出来了,看到了没有,每个Student节点下面都有一个Teacher节点,当这段XML被接纳方转化为Student数组时,每个学生都有了一个自己的教师,Teacher目标被仿制了成百上千次,通过这么一个转化--传输--转化的进程,这个数组目标真的成了一个“庞然大物”。

问题的本源在于Student和Teacher之间的联系是多对一,当传送“多”方时,“一”方有或许会被仿制屡次。然后占用很多网络传输带宽和内存。在这儿参数不必定非要是一个调集或许数组,例如ObjectA和ObjectB都有一个对ObjectC的引证,通过SOAP传送往后,ObjectC就由一个变成两个了,别离归于ObjectA和ObjectB,而不再是同享一个ObjectC了。

【修改引荐】

  1. XML WebService彻底实例具体解析
  2. XML新手入门 创立结构杰出的XML
  3. 完成XML和Web服务时要防止的三种常见过错
转载请说明出处
知优网 » 详解WebService开发中四个常见问题(调用webservices出错什么意思)

发表评论

您需要后才能发表评论