@Test public void testQueryRemainningWS() throws InterruptedException, MalformedURLException, ServiceException, RemoteException { Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(new URL("http://localhost:8080/AccountInfo")); call.setOperationName(new QName("http://accountinfo", "queryRemainning")); String ret = (String) call.invoke( new Object[] { "C01" } ); assertNotNull(ret); assertEquals("100.0",ret); }
原理也很简单,就是按照axis的客户端要求发起web服务调用看看结果。我运行后发现找不到queryRemainning方法,于是debug进去看看。发现tuscany在InterfaceContractMapperImpl.map(Interface, Operation),这个函数里面做了接口与操作的转换。我的目的是wsdl转java,在这里比较的时候步骤比较多,其中有个步骤会比较两个接口是不是都是remotable的,如下:
public boolean isCompatible(Operation source, Operation target, boolean remotable) { label0: { if(source == target) return true; if(source.isDynamic() || target.isDynamic()) return true; if(!source.getName().equals(target.getName())) return false; if(source.getInterface().isRemotable() != target.getInterface().isRemotable()) return false; DataType sourceOutputType = source.getOutputType(); DataType targetOutputType = target.getOutputType(); if(!isCompatible(targetOutputType, sourceOutputType, remotable)) return false; boolean checkSourceWrapper = true; List sourceInputType = (List)source.getInputType().getLogical(); if(source.isInputWrapperStyle() && source.getInputWrapper() != null) { sourceInputType = (List)source.getInputWrapper().getUnwrappedInputType().getLogical(); checkSourceWrapper = false; } boolean checkTargetWrapper = true; List targetInputType = (List)target.getInputType().getLogical(); if(target.isInputWrapperStyle() && target.getInputWrapper() != null) { targetInputType = (List)target.getInputWrapper().getUnwrappedInputType().getLogical(); checkTargetWrapper = false; } if(checkSourceWrapper != checkTargetWrapper) return true; if(sourceInputType.size() != targetInputType.size()) return false; int size = sourceInputType.size(); for(int i = 0; i < size; i++) if(!isCompatible((DataType)sourceInputType.get(i), (DataType)targetInputType.get(i), remotable)) return false; Iterator i$ = target.getFaultTypes().iterator(); boolean found; label1: do { if(!i$.hasNext()) break label0; DataType targetFaultType = (DataType)i$.next(); found = true; Iterator i$ = source.getFaultTypes().iterator(); DataType sourceFaultType; do { if(!i$.hasNext()) continue label1; sourceFaultType = (DataType)i$.next(); found = false; } while(!isCompatible(targetFaultType, sourceFaultType, remotable)); found = true; } while(found); return false; } return true; }
在代码中11行的地方return了,于是查的新的tuscany要求java接口必须声明为remotable才可以发布为外部service。这里tuscany用了值传递,也就是用xml做wsdl和java接口之间的数据传递。
这是关于remotable接口的说明:
Annotation used to indicate a Java interface as remotable. Remotable interfaces use pass-by-value semantics, can be published as entry points and used for external services.
将原有代码的interface加remotable 注解后程序跑通!!!
package samples; import org.osoa.sca.annotations.Remotable; @Remotable public interface AccountInfo { public String queryRemainning(String accountId); }