package org.wix.wsCaller; import org.apache.axis.Constants; import org.apache.axis.encoding.ser.SimpleDeserializer; import org.apache.axis.wsdl.gen.Parser; import org.apache.axis.wsdl.symbolTable.*; import javax.wsdl.*; import javax.xml.namespace.QName; import javax.xml.rpc.Call; import javax.xml.rpc.encoding.Deserializer; import javax.xml.rpc.encoding.DeserializerFactory; import java.util.*; /** * 服务调用得类,现在只限于无复杂类型参数和返回值得情 ,这里参考了网络上得一份开源代码 * * @author T-Bag.& neusoftware_20063500 * */ public class ServiceCaller { private Parser wsdlParser = null; private Map<String, ServiceEntry> services = null; @SuppressWarnings("unchecked") public ServiceCaller(String wsdlURL) throws Exception { wsdlParser = new Parser(); wsdlParser.run(wsdlURL); // 解析WSDL services = getEntries(ServiceEntry.class);// 得到服务得入口 } /** * 调用服务 * * @param serviceName * 服务名 * @param portName * 接口名 * @param operationName * 操作名 * @param parameterValues * 参数 * @return 返回值 * @throws Exception */ public Map invoke(String serviceName, String portName, String operationName, Vector<Object> parameterValues) throws Exception { Vector<Object> inputs = new Vector<Object>(); String returnName = null; ServiceEntry serviceEntry = (ServiceEntry) services.get(serviceName); Service service = serviceEntry.getService(); org.apache.axis.client.Service clientService = new org.apache.axis.client.Service( wsdlParser, service.getQName());// 根据解析气和服务得QName,获得服务实例 Call call = clientService.createCall(QName.valueOf(portName), QName .valueOf(operationName));// 有了服务以后,就根据接口和操作获得调用Call对象 ((org.apache.axis.client.Call) call).setTimeout(new Integer(15 * 1000));// 设置超时时间 BindingEntry bindingEntry = getBindingEntry(serviceName, portName); Operation o = getOperation(bindingEntry, operationName); Parameters parameters = bindingEntry.getParameters(o); // 执行有返回值 if (parameters.returnParam != null) { QName returnQName = parameters.returnParam.getQName(); returnName = returnQName.getLocalPart();// 结果名 } int size = parameters.list.size();// 遍历所有参数,包括输入和输出 for (int i = 0; i < size; i++) { Parameter p = (Parameter) parameters.list.get(i); switch (p.getMode()) {// 判断输入输出类型 case Parameter.IN: inputs.add(getParamData((org.apache.axis.client.Call) call, p, (String) parameterValues.elementAt(i)));// parameterValues是用户得输入 break; case Parameter.OUT: break; case Parameter.INOUT: inputs.add(getParamData((org.apache.axis.client.Call) call, p, (String) parameterValues.elementAt(i))); break; } } Object ret = call.invoke(inputs.toArray());// 调用服务 Map outputs = call.getOutputParams(); HashMap map = new HashMap(); if (ret != null && returnName != null) { map.put(returnName, ret);// 结果名 -- 结果 } if (outputs != null) { for (Iterator i = outputs.keySet().iterator(); i.hasNext();) { Object obj = i.next(); String name; Object value; if (obj.getClass().getName().equals("java.lang.String")) { name = (String) obj; } else { name = ((QName) obj).getLocalPart(); } value = outputs.get(obj); map.put(name, value);// 具体得结果每个参数 } } return map; } /** * 遍历获得服务名列表 * * @return */ public Vector enumServiceNames() { Vector v = new Vector(); Iterator i = services.keySet().iterator(); while (i.hasNext()) { String s = (String) i.next(); v.addElement(s); } return v; } /** * 根据服务,获得接口列表 * * @param serviceName * @return */ public Vector enumPortNames(String serviceName) { Vector v = new Vector(); ServiceEntry serviceEntry = (ServiceEntry) services.get(serviceName); // 根据服务名,获得服务入口,得到他得所有接口 Map ports = serviceEntry.getService().getPorts(); Iterator i = ports.keySet().iterator(); while (i.hasNext()) { String s = (String) i.next(); v.addElement(s); } return v; } /** * 根据服务和接口,获得操做列表 * * @param serviceName * @param portName * @return */ public Vector enumOperationNames(String serviceName, String portName) { Vector v = new Vector(); BindingEntry entry = getBindingEntry(serviceName, portName); Set operations = entry.getOperations(); Iterator i = operations.iterator(); while (i.hasNext()) { Operation o = (Operation) i.next(); String s = o.getName(); v.addElement(s); } return v; } public Parameters enumParameters(String serviceName, String portName, String operationName) { // 获得制定端口得绑定 BindingEntry entry = getBindingEntry(serviceName, portName); // 获取特定得操作 Operation o = getOperation(entry, operationName); // 获取参数列表 Parameters parameters = entry.getParameters(o); return parameters; } /** * 根据参数,获得其类型 * * @param p * @return */ public String getParameterModeString(Parameter p) { String ret = null; switch (p.getMode()) { case Parameter.IN: ret = "[IN]"; break; case Parameter.INOUT: ret = "[IN, OUT]"; break; case Parameter.OUT: ret = "[OUT]"; break; } return ret; } /** * 根据服务,获得端口列表,然后获得制定得端口,再获取这个端口得绑定 * * @param serviceName * @param portName * @return */ private BindingEntry getBindingEntry(String serviceName, String portName) { ServiceEntry serviceEntry = (ServiceEntry) services.get(serviceName); Port port = serviceEntry.getService().getPort(portName); Binding binding = port.getBinding(); SymbolTable table = wsdlParser.getSymbolTable(); return table.getBindingEntry(binding.getQName()); } /** * 获得绑定上得操作 * * @param entry * @param operationName * @return */ private Operation getOperation(BindingEntry entry, String operationName) { Set operations = entry.getOperations(); Iterator i = operations.iterator(); while (i.hasNext()) { Operation o = (Operation) i.next(); if (operationName.equals(o.getName())) { return o; } } return null; } // return Map of <QName.getLocalPart, SymTabEntry> // SymTabEntry这个是很多得父类,比如说,是BindingEntry, ContainedEntry, // MessageEntry, PortEntry, PortTypeEntry, ServiceEntry, TypeEntry, // 那么我们就可以知道了 private Map getEntries(Class cls) { HashMap ret = new HashMap(); HashMap map = wsdlParser.getSymbolTable().getHashMap(); // 遍历这个表,获得特定类型得Map,这个类型就根据传进来得Class, // 可以是PortTypeEntry, ServiceEntry... Iterator iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); QName key = (QName) entry.getKey(); Vector v = (Vector) entry.getValue(); int size = v.size(); for (int i = 0; i < size; ++i) { SymTabEntry symTabEntry = (SymTabEntry) v.elementAt(i); if (cls.isInstance(symTabEntry))// 判断类型 { ret.put(key.getLocalPart(), symTabEntry); // key.getLocalPart()就是服务名其实 } } } return ret; } /** * 根据p得类型,将arg转换成这个类型得对象,并且返回 * * @param c * @param p * @param arg * @return * @throws Exception */ private Object getParamData(org.apache.axis.client.Call c, Parameter p, String arg) throws Exception { // Get the QName representing the parameter type QName paramType = org.apache.axis.wsdl.toJava.Utils.getXSIType(p); TypeEntry type = p.getType(); // 判断参数是否为基本数据类型,如果是基本数据类型,就可以将arg转换为这个类型,并且返回 if (type instanceof BaseType && ((BaseType) type).isBaseType()) { DeserializerFactory factory = c.getTypeMapping().getDeserializer( paramType); Deserializer deserializer = factory .getDeserializerAs(Constants.AXIS_SAX); if (deserializer instanceof SimpleDeserializer) { return ((SimpleDeserializer) deserializer).makeValue(arg); } } throw new RuntimeException("not know how to convert '" + arg + "' into " + c); } }