基于Axis服务端的webservice客户端实现

落日映苍穹つ 2022-06-18 06:26 516阅读 0赞

之前开发webservice客户端的时候遇到一个使用Axis2开发接口的厂家,查资料把Axis1和Axis2客户端的开发方式总结如下:

基于Axis1服务端的客户端实现:

  1. /**
  2. * 使用Axis Call Client动态调用WebService
  3. * @param requestXml 请求报文
  4. * @param wsdl webservice地址
  5. * @param targetNamespace 命名空间
  6. * @param webServiceMethod 访问的方法名
  7. * @return
  8. */
  9. public String getRespByAxisCallClient(String requestXml, String wsdl,String targetNamespace, String webServiceMethod){
  10. String respXml = "";
  11. try{
  12. Service service = new Service();
  13. Call call = (Call) service.createCall();
  14. //设置要访问的WSDL地址
  15. call.setTargetEndpointAddress(new URL(wsdl));
  16. //设置要访问的方法名
  17. call.setOperationName(new QName(wsdl,webServiceMethod));
  18. //设置参数
  19. call.addParameter("XMLFrom", XMLType.XSD_STRING, ParameterMode.IN);
  20. //设置返回值类型
  21. call.setReturnType(XMLType.XSD_STRING);
  22. //调用服务
  23. respXml = (String) call.invoke(new Object[] { requestXml.toString() });
  24. }catch(Exception e){
  25. logger.error("服务调用异常",e);
  26. }
  27. return respXml;
  28. }

Call在线API:http://axis.apache.org/axis/java/apiDocs/org/apache/axis/client/Call.html

基于Axis2服务端的客户端实现:

方法一:

采用RPC的方式进行远程调用,通过URL定位告诉远程服务器需要调用的方法名、参数等,调用远程服务,获取结果。如果被调用的WebService方法有返回值,应使invokeBlocking 方法 该方法有三个参数:第一个参数的类型是QName对象,表示要调用的方法名;第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];

当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}。第三个参数表示WebService方法的 返回值类型的Class对象,参数类型为Class[]。如果被调用的WebService方法没有返回值 应使用 invokeRobust 方法。该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是 元素的targetNamespace属性值。方法如下:

  1. /**
  2. * 方法一:RPC调用webservice Axis2服务
  3. * @param wsdl 接口服务端调用地址
  4. * @param webServiceMethod 调用方法
  5. * @param inParam 请求参数
  6. * @param targetNamespace 命名空间
  7. * @return
  8. */
  9. public String getRespByAxisRPCClient(Map<String,Object> inParam, String wsdl,String targetNamespace, String webServiceMethod){
  10. String responseStr = "";
  11. RPCServiceClient serviceClient = null;
  12. try{
  13. //获取RPCServiceClient对象
  14. serviceClient = new RPCServiceClient();
  15. //获取Options对象
  16. Options options = serviceClient.getOptions();
  17. //指定调用webservice的URL
  18. EndpointReference targetERP = new EndpointReference(wsdl);
  19. options.setTo(targetERP);
  20. //指定要调用的方法及wsdl文件的命名空间
  21. QName opAddEntry = new QName("http://ws.apache.org/axis2",webServiceMethod);
  22. //指定method的入参
  23. Object[] opAddEntryArgs = inParam.values().toArray();
  24. //指定方法返回值的数据类型class对象
  25. Class[] classes = new Class[]{String.class};
  26. //调用服务
  27. responseStr = (String) serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs,classes)[0];
  28. }catch(Exception e){
  29. logger.error("RPCServiceClient error",e);
  30. throw new RuntimeException("RPCServiceClient error",e);
  31. }finally{
  32. try {
  33. serviceClient.cleanupTransport();
  34. } catch (AxisFault e) {
  35. logger.error("RPCServiceClient cleanupTransport error",e);
  36. throw new RuntimeException("RPCServiceClient error",e);
  37. }
  38. }
  39. return responseStr;
  40. }

注意:

1、如果被调用的WebService方法有返回值,应使用invokeBlocking方法,该方法有三个参数:

第一个参数的类型是QName对象,表示要调用的方法名;

第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}。

第三个参数表示WebService方法的,返回值类型的Class对象,参数类型为Class[]。

2、如果返回对象是String类型的字符串,参数为String.class;如果返回对象是double类型的数字,参数为double.class。

3、如果被调用的WebService方法没有返回值,应使用invokeRobust方法:该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。

在开发过程中遇到以下错误:

错误一:

Center

查找资料发现问题出在缺少必要的jar包上,经测试得知,使用RPCServiceClient所需的最少jar包如下:

  1. axiom-api-1.2.13.jar
  2. axiom-impl-1.2.13.jar
  3. axis2-adb-1.6.2.jar
  4. axis2-kernel-1.6.2.jar
  5. axis2-transport-http-1.6.2.jar
  6. axis2-transport-local-1.6.2.jar
  7. commons-codec-1.3.jar
  8. commons-httpclient-3.1.jar
  9. commons-logging-1.1.1.jar
  10. httpcore-4.0.jar
  11. neethi-3.0.2.jar
  12. wsdl4j-1.6.2.jar
  13. XmlSchema-1.4.7.jar

错误二:

  1. 原因:webservice调用连接池默认只有两个连接,每次调用完必须释放连接,否则很快就会没连接。需要在finally中加入以下代码,释放掉已有的连接。
  2. finally{
  3. try {
  4. serviceClient.cleanupTransport();
  5. } catch (AxisFault e) {
  6. logger.error("RPCServiceClient cleanupTransport error",e);
  7. throw new RuntimeException("RPCServiceClient error",e);
  8. }
  9. }

错误三:

Center 1
原因:缺少jar包 mail-1.4.jar

方法二:

  1. /**
  2. * 方法二: 应用document方式调用 webservice服务,用ducument方式可以摆脱我们不想要的耦合
  3. * @param wsdl webservice地址
  4. *
  5. */
  6. public static void getRespByDocument(String wsdl,String user,String password) {
  7. try {
  8. //获取Options对象
  9. Options options = new Options();
  10. // 指定调用WebService的URL
  11. EndpointReference targetEPR = new EndpointReference(wsdl);
  12. options.setTo(targetEPR);
  13. // options.setAction("urn:getPrice");
  14. //获取ServiceClient对象
  15. ServiceClient serviceClient = new ServiceClient();
  16. serviceClient.setOptions(options);
  17. OMFactory fac = OMAbstractFactory.getOMFactory();
  18. String tns = "http://quickstart.samples/";
  19. // 命名空间,有时命名空间不增加没事,不过最好加上,因为有时会出问题
  20. OMNamespace omNs = fac.createOMNamespace(tns, "");
  21. OMElement method = fac.createOMElement("getPrice", omNs);
  22. OMElement symbol = fac.createOMElement("symbol", omNs);
  23. // symbol.setText("1");
  24. symbol.addChild(fac.createOMText(symbol, "Axis2 Echo String "));
  25. method.addChild(symbol);
  26. method.build();
  27. //为SOAP Header构造验证信息
  28. addValidation(serviceClient,tns,user,password);
  29. //调用服务
  30. OMElement result = serviceClient.sendReceive(method);
  31. }catch (AxisFault axisFault) {
  32. axisFault.printStackTrace();
  33. }
  34. }
  35. /**
  36. * 为SOAP Header构造验证信息,
  37. * 如果你的服务端是没有验证的,那么你不用在Header中增加验证信息
  38. *
  39. * @param serviceClient
  40. * @param tns 命名空间
  41. * @param user
  42. * @param passwrod
  43. */
  44. public static void addValidation(ServiceClient serviceClient, String tns , String user, String passwrod) {
  45. OMFactory fac = OMAbstractFactory.getOMFactory();
  46. OMNamespace omNs = fac.createOMNamespace(tns, "nsl");
  47. OMElement header = fac.createOMElement("AuthenticationToken", omNs);
  48. OMElement ome_user = fac.createOMElement("Username", omNs);
  49. OMElement ome_pass = fac.createOMElement("Password", omNs);
  50. ome_user.setText(user);
  51. ome_pass.setText(passwrod);
  52. header.addChild(ome_user);
  53. header.addChild(ome_pass);
  54. serviceClient.addHeader(header);
  55. }

发表评论

表情:
评论列表 (有 0 条评论,516人围观)

还没有评论,来说两句吧...

相关阅读