• java对接webservice接口的四种方式


    这两天一直在做外系统对接,对方的接口是webservice的形式,调用起来有些蛋疼,于是在这里记录一下我尝试过的调用WebService的三种方式。

    方式一:以HttpURLConnection的方式调用
    1. String url ="http://127.0.0.1/cwbase/Service/hndg/Hello.asmx?wsdl";
    2. URL realURL = new URL(url);
    3. HttpURLConnection connection = (HttpURLConnection) realURL.openConnection();
    4. connection.setDoOutput(true);
    5. connection.setDoInput(true);
    6. connection.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
    7. connection.setRequestProperty("content-length",String.valueOf(xmlData.length));
    8. connection.setRequestMethod("POST");
    9. DataOutputStream printOut = new DataOutputStream(connection.getOutputStream());
    10. printOut.write(xmlOutString.getBytes("UTF-8"));//xmlOutString是自己拼接的xml,这种方式就是通过xml请求接口
    11. printOut.flush();
    12. printOut.close();
    13. // 从连接的输入流中取得回执信息
    14. InputStream inputStream = connection.getInputStream();
    15. InputStreamReader isr = new InputStreamReader(inputStream,"UTF-8");
    16. BufferedReader bufreader = new BufferedReader(isr);
    17. String xmlString = "";
    18. int c;
    19. while ((c = bufreader.read()) != -1) {
    20. xmlString += (char) c; }
    21. isr.close();
    22. //处理返回的xml信息
    23. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    24. DocumentBuilder db = dbf.newDocumentBuilder();
    25. Document d = db.parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")));
    26. //从对方的节点中取的返回值(节点名由对方接口指定)
    27. String returnState = d.getElementsByTagName("ReturnStatus").item(0).getFirstChild().getNodeValue();
    方式二:使用apache-cxf生成java类调用

    下载apache-cxf并配置环境变量(参照JAVA环境变量配置),配置成功后cmd输入wsdl2java -help即可验证是否成功。
    接着在cmd中输入wsdl2java -encoding utf-8 -d 生成路径 接口地址,即可在指定路径生成接口JAVA文件,生成后的JAVA类如下图:
    在这里插入图片描述

    生成以后调用起来就很简单了,例子如下:

    1. String result = "";
    2. NC65To63ProjectService service = new NC65To63ProjectService();
    3. NC65To63ProjectServicePortType servicePort =service.
    4. getNC65To63ProjectServiceSOAP11PortHttp();
    5. result = servicePort.receiptProject(json);

    方式三:使用AXIS调用WebService

    为了避免找不到对方包,所以我直接把包贴在顶上了。

    1. import org.apache.axis.client.Service;
    2. import org.apache.axis.client.Call;
    3. import org.apache.axis.encoding.XMLType;
    4. import javax.xml.namespace.QName;
    5. import javax.xml.rpc.ParameterMode;
    6. String result = "";
    7. String url = "http://127.0.0.1/uapws/service/nc65to63projectsysplugin";//这是接口地址,注意去掉.wsdl,否则会报错
    8. Service service = new Service();
    9. Call call = (Call) service.createCall();
    10. call.setTargetEndpointAddress(url);
    11. String parametersName = "string";//设置参数名
    12. call.setOperationName("receiptProject");//设置方法名
    13. call.addParameter(parametersName, XMLType.XSD_STRING, ParameterMode.IN);//方法参数,1参数名、2参数类型、3.入参
    14. call.setReturnType(XMLType.XSD_STRING);//返回类型
    15. String str = json;
    16. Object resultObject = call.invoke(new Object[] { str });//调用接口
    17. result = (String) resultObject;

    方式四:试用httpclient

    1. public static void main(String args[]) {
    2. // 第一种方法 ----------------------------------------------
    3. JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
    4. // 创建客户端连接
    5. Client client = factory.createClient("http://127.0.0.1:8080/xx/service/userOrg?wsdl");
    6. Object[] res = null;
    7. try {
    8. QName operationName = new QName("http://impl.webservice.userorg.com/","findUser");//如果有命名空间需要加上这个,第一个参数为命名空间名称,调用的方法名称
    9. res = client.invoke(operationName, "admin");//后面为WebService请求参数数组
    10. System.out.println(res[0]);
    11. }catch (Exception e) {
    12. e.printStackTrace();
    13. }
    14. // 第二种方法 ----------------------------------------------
    15. // 被这个标记所包含的内容将表示为纯文本
    16. String xmlData = "" +
    17. "" +
    18. "" +
    19. "帐号ID(必填)" +
    20. "密码" +
    21. "密码" +
    22. "其中userPasswordSHA1标签代表SHA1加密后的密码,userPasswordMD5标签代表MD5加密后的密码" +
    23. "姓名" +
    24. "" +
    25. "描述 " +
    26. "邮箱 " +
    27. "性别" +
    28. "电话号码" +
    29. "移动电话" +
    30. "用户的开始生效时间(YYYY-MM-DD HH:mm:SS)" +
    31. "用户结束生效时间(YYYY-MM-DD HH:mm:SS) " +
    32. "身份证号码" +
    33. "工号 " +
    34. "用户所属的组织的编码号 " +
    35. "用户类型" +
    36. "所在公司名称 " +
    37. "" +
    38. "]]>";
    39. //调用方法
    40. String method = "sayHello";
    41. method = "getUserList";
    42. String data=""+
    43. ""+
    44. "+method+">"+
    45. ""+ xmlData + ""+
    46. "+method+">"+
    47. ""+
    48. "";
    49. String httpUrl="http://127.0.0.1:8080/xx/service/helloWorld?wsdl";
    50. httpUrl="http://127.0.0.1:8080/xx/service/userOrg?wsdl";
    51. try {
    52. //第一步:创建服务地址
    53. URL url = new URL(httpUrl);
    54. //第二步:打开一个通向服务地址的连接
    55. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    56. //第三步:设置参数
    57. //3.1发送方式设置:POST必须大写
    58. connection.setRequestMethod("POST");
    59. //3.2设置数据格式:content-type
    60. connection.setRequestProperty("content-type", "text/xml;charset=utf-8");
    61. //3.3设置输入输出,因为默认新创建的connection没有读写权限,
    62. connection.setDoInput(true);
    63. connection.setDoOutput(true);
    64. //第四步:组织SOAP数据,发送请求
    65. String soapXML = data;
    66. //将信息以流的方式发送出去
    67. // DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写到流里面
    68. OutputStream os = connection.getOutputStream();
    69. os.write(soapXML.getBytes());
    70. //第五步:接收服务端响应,打印
    71. int responseCode = connection.getResponseCode();
    72. System.out.println("responseCode: "+responseCode);
    73. if(200 == responseCode){//表示服务端响应成功
    74. //获取当前连接请求返回的数据流
    75. InputStream is = connection.getInputStream();
    76. InputStreamReader isr = new InputStreamReader(is);
    77. BufferedReader br = new BufferedReader(isr);
    78. StringBuilder sb = new StringBuilder();
    79. String temp = null;
    80. while(null != (temp = br.readLine())){
    81. sb.append(temp);
    82. }
    83. is.close();
    84. isr.close();
    85. br.close();
    86. System.out.println(StringEscapeUtils.unescapeXml(sb.toString())); //转义
    87. System.out.println(sb.toString());
    88. } else { //异常信息
    89. InputStream is = connection.getErrorStream(); //通过getErrorStream了解错误的详情,因为错误详情也以XML格式返回,因此也可以用JDOM来获取。
    90. InputStreamReader isr = new InputStreamReader(is,"utf-8");
    91. BufferedReader in = new BufferedReader(isr);
    92. String inputLine;
    93. BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
    94. new FileOutputStream("d:\\result.xml")));// 将结果存放的位置
    95. while ((inputLine = in.readLine()) != null)
    96. {
    97. System.out.println(inputLine);
    98. bw.write(inputLine);
    99. bw.newLine();
    100. bw.close();
    101. }
    102. in.close();
    103. }
    104. os.close();
    105. } catch (Exception e) {
    106. System.out.println(e.getMessage());
    107. }
    108. }
    109. // 把xml转义
    110. public static String escapeXml(String xml) {
    111. String newXml = xml.replaceAll("<", "<").replaceAll(">", ">").replaceAll(" ", " ").replaceAll("\"", """);
    112. return newXml;
    113. }

    总结

    第一种使用HttpURLConnection调用的方法,基本不用担心什么兼容问题,但是通过xml请求接口,需要自己手动拼接xml(一般通过soapui生成,然后在程序中根据情况拼接),并且返回的数据也是xml,还要通过代码解析,可以说是极其麻烦了。

    第二种apache-cxf生成java类调用的方式,直接调用生成的类即可访问接口,非常方便,但是apache-cxf和jdk有兼容问题,如果关联的某个jar包中的代码有冲突,就会遇到痛苦的报错了。在我的尝试中,就有一个Service冲突的问题,网上说需要更改某jar包中的class文件,但是由于项目太过庞大,担心会触发其他的问题,所以我只能就此作罢。

    重点来了,第三种AXIS的方式, 没有啥兼容问题的方式了,调用起来非常简便,不需要拼接xml,返回的也只能干净的数据,

    第四种:

    httpclient本人亲测好用。不用引用cxf或AXIS一大堆jar包,比较方便

  • 相关阅读:
    vscode拉取git代码到本地提示 在签出前,请清理存储库工作树
    BI报表与数据开发
    交通物流模型 | 基于自适应图卷积网络的轨道交通短时客流预测
    第四章. Pandas进阶—数据移位
    使用UICollectionView制作轮播图(一)
    01.06 校招 实习 内推 面经
    java 各种架构图汇总
    索引失效的几种情况
    【无标题】
    通义灵码牵手阿里云函数计算 FC ,打造智能编码新体验
  • 原文地址:https://blog.csdn.net/zhaofuqiangmycomm/article/details/132732402