我找到了一篇来自2004年的文章this article,声称没有实际标准,只有最佳实践。是否有更好的解决方案?你如何解决WS版本控制?
问题描述
系统A
客户端
class SystemAClient{
SystemBServiceStub systemB;
public void consumeFromB(){
SystemBObject bObject = systemB.getSomethingFromB(new SomethingFromBRequest("someKey"));
}
}
服务
class SystemAService{
public SystemAObject getSomethingFromA(SomethingFromARequest req){
return new SystemAObjectFactory.getObject(req);
}
}
可转移对象
版本1
class SystemAObject{
Integer id;
String name;
... // getters and setters etc;
}
版本 2
class SystemAObject{
Long id;
String name;
String description;
... // getters and setters etc;
}
请求对象
版本 1
class SomethingFromARequest {
Integer requestedId;
... // getters and setters etc;
}
版本 2
class SomethingFromARequest {
Long requestedId;
... // getters and setters etc;
}
系统 B
客户端
class SystemBClient{
SystemAServiceStub systemA;
public void consumeFromA(){
SystemAObject aObject = systemA.getSomethingFromA(new SomethingFromARequest(1));
aObject.getDescription() // fail point
// do something with it...
}
}
服务
class SystemBService{
public SystemBObject getSomethingFromB(SomethingFromBRequest req){
return new SystemBObjectFactory.getObject(req);
}
}
可转移对象
版本1
class SystemBObject{
String key;
Integer year;
Integer month;
Integer day;
... // getters and setters etc;
}
版本 2
class SystemBObject{
String key;
BDate date;
... // getters and setters etc;
}
class BDate{
Integer year;
Integer month;
Integer day;
... // getters and setters etc;
}
请求对象
版本 1
class SomethingFromBRequest {
String key;
... // getters and setters etc;
}
版本2
class SomethingFromBRequest {
String key;
BDate afterDate;
BDate beforeDate;
... // getters and setters etc;
}
失败场景
如果版本1的System A 客户端调用版本2的System B 服务,可能会出现以下问题:
SystemBObject
缺少方法(getYear()
,getMonth()
,getDay()
)- 未知类型
BDate
如果版本2的System A 客户端调用版本1的System B 服务,可能会出现以下问题:
SomethingFromBRequest
中的BDate
类型未知(客户端使用新的B请求对象,但是B版本1不识别)- 如果System A客户端足够聪明地使用请求对象的版本1,则可能会在
SystemBObject
对象的缺少方法(getDate()
)上失败。
如果版本1的System B 客户端调用版本2的System A 服务,可能会出现以下问题:
SystemAObject
的类型不匹配或溢出(返回Long
但期望Integer
)
SystemARequest
上的类型不匹配或溢出(请求Long
而不是Integer
)- 如果请求以某种方式传递,则存在强制转换问题(存根为
Long
,但服务返回一个Integer
,在所有WS实现中不一定兼容)
可能的解决方案
- 在升级版本时使用数字:例如
SystemAObject1
,SystemBRequest2
等,但这缺少匹配源/目标版本的API - 在签名中传递XML而不是对象(令人讨厌,在XML中传递转义的XML,双重序列化,反序列化/解析,取消解析)
- 其他:例如文档/字面/ WS-I有补救措施吗?