java程序调用webService接口(这边是c++写的webService服务)

最近在解决一个设备强制校时(对设备时间不准的问题进行校时)的一个任务,该任务设计到一个调用C++写的一个校时服务,需要在java的程序中进行调用,因为以前没有做过到调用外部服务的,所以查了很多资料,终于解决了,记录一下。顺带给有需要的朋友一点帮助。

我拿到一个服务后,如下图:

(1)、打开ns.wsdl文件,看到如下(具体不用看,只看最下面几行就好)

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="Service"
  targetNamespace="http://tempuri.org/ns.xsd/Service.wsdl"
  xmlns:tns="http://tempuri.org/ns.xsd/Service.wsdl"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  .......
  xmlns="http://schemas.xmlsoap.org/wsdl/">

<types>

  <schema targetNamespace="http://tempuri.org/ns.xsd"
 ................
    attributeFormDefault="unqualified">
    <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
    <!-- operation request element -->
    <element name="Calibration">
      <complexType>
          <sequence>
            <element name="Factory-code" type="xsd:int" minOccurs="1" maxOccurs="1"/><!-- ns__Calibration::Factory_code -->
            <element name="strIP" type="xsd:string" minOccurs="0" maxOccurs="1"/><!-- ns__Calibration::strIP -->
            <element name="nPort" type="xsd:int" minOccurs="1" maxOccurs="1"/><!-- ns__Calibration::nPort -->
            <element name="strUserName" type="xsd:string" minOccurs="0" maxOccurs="1"/><!-- ns__Calibration::strUserName -->
            <element name="strPasswd" type="xsd:string" minOccurs="0" maxOccurs="1"/><!-- ns__Calibration::strPasswd -->
          </sequence>
      </complexType>
    </element>
   ...........
  </schema>

</types>

<message name="CalibrationRequest">
  <part name="Body" element="ns:Calibration"/><!-- ns__Calibration::ns__Calibration -->
</message>

..........

<service name="Service">
  <documentation>gSOAP 2.8.39 generated service definition</documentation>
  <port name="Service" binding="tns:Service">
    <SOAP:address location="http://localhost:8080"/>
  </port>
</service>

</definitions>

(2)、启动服务(就是.exe文件)

(3)、访问我标注的地址在后面添加/?wsdl。如: http://localhost:8080/?wsdl去在浏览器上看这个地址的内容,具体格式可以看网上查询号码的webService的wsdl文件http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl。如果可以显示的这样格式的内容的话,然后再在soapUI软件访问

(4)、点击ok后,在左侧会多一个项目,双击你要的调用的方法,会打开一个窗口,你把?替换成你要传个服务接口的参数

(5)、点击左上角的运行按钮运行,如果右侧可以出来结果,这接口可以进行交互。

然后在java后台开始写接口了。我是写在controller层的,前端点击按钮后去调用这个方法,进行服务接口的访问。

/**
 * 强制校时
 *
 * @param request
 * @param response
 * @return
 * @throws JsonProcessingException
 */
@RequestMapping(params = "act=compulsorySchoolTimeThree", method = {RequestMethod.POST, RequestMethod.GET})
public Map<String, Object> compulsorySchoolTimeThree(HttpServletRequest request, HttpServletResponse response) {
   Map<String, Object> resultMap = null;
   String URL = "http://localhost:8080";
   try {
      String urlStr = URL;
      java.net.URL url = new URL(urlStr);
      HttpURLConnection con = (HttpURLConnection) url.openConnection();
      con.setDoInput(true);
      con.setDoOutput(true);
      con.setRequestMethod("POST");
      con.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
      OutputStream oStream = con.getOutputStream();
      //下面这行代码是用字符串拼出要发送的xml,xml的内容是从测试软件里拷贝出来的
      //需要注意的是,有些空格不要弄丢哦,要不然会报500错误的。
      //参数什么的,你可以封装一下方法,自动生成对应的xml脚本
      String soap = strSoap(498, "120.114.3.211",2043,"dsfdsf","sdfsfd");
      oStream.write(soap.getBytes());
      oStream.close();
      InputStream iStream = con.getInputStream();
      Reader reader = new InputStreamReader(iStream);
      int tempChar;
      String str = new String();
      while ((tempChar = reader.read()) != -1) {
         str += (char) tempChar;
      }
      //下面这行输出返回的xml到控制台,相关的解析操作大家自己动手喽。
      //如果想要简单的话,也可以用正则表达式取结果出来。
      System.out.println(">>>>>>>>>>>>>>>>>>>>>>>returnedxmlstr:" + str);
      iStream.close();
      oStream.close();
      con.disconnect();
   } catch (Exception e) {
      e.printStackTrace();
   }
   return resultMap;
}

public static String strSoap(int factoryCode, String strIp, int nPort, String strUserName,String strPasswd){
   String soap = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"http://tempuri.org/ns.xsd\"> " +
         "   <soapenv:Header/> " +
         "   <soapenv:Body> " +
         "      <ns:Calibration> " +
         "         <Factory-code>"+ factoryCode +"</Factory-code> " +
         "       <!--Optional:-->                        " +
         "         <strIP>"+ strIp +"</strIP>             " +
         "         <nPort>"+ nPort +"</nPort>             " +
         "       <!--Optional:-->                        " +
         "         <strUserName>"+ strUserName +"</strUserName>   " +
         "       <!--Optional:-->                        " +
         "         <strPasswd>"+ strPasswd +"</strPasswd>       " +
         "         <Factory-code>"+ factoryCode +"</Factory-code> " +*/
         "      </ns:Calibration> " +
         "   </soapenv:Body> " +
         "</soapenv:Envelope>";
   return soap;
}

这样访问就可以测试通了,本人已测试,ok如果有问题可以留言,我会尽可能帮助大家

 

下面也有两种通过RPC方式进行调用用的,但是不清楚为啥掉不同我的服务,但是调用晚上的服务是可以的,你们可以了解一下,也是一种调用方法

/**
 * 强制校时
 *
 * @param request
 * @param response
 * @return
 * @throws JsonProcessingException
 */
@RequestMapping(params = "act=compulsorySchoolTime", method = {
      RequestMethod.POST, RequestMethod.GET
})
public Map<String, Object> compulsorySchoolTime(HttpServletRequest request, HttpServletResponse response) {
   Map<String, Object> resultMap = null;

   try {
      // 使用RPC方式调用WebService
      RPCServiceClient serviceClient = new RPCServiceClient();
      // 创建WSDL的URL,注意不是服务地址
      String url = "http://localhost:8080";
      // 指定调用WebService的URL
      EndpointReference targetEPR = new EndpointReference(url);
      Options options = serviceClient.getOptions();
      // 确定目标服务地址
      options.setTo(targetEPR);
      // 确定调用方法(wsdl 命名空间地址 (wsdl文档中的targetNamespace) 和 方法名称 的组合)
      options.setAction("http://localhost:8080/Calibration");
      // 指定方法的参数值
      Object[] parameters = new Object[] {498, "120.114.3.211",2043,"dsfdsf","sdfsfd"};
      // 创建服务名称
      // 1.namespaceURI - 命名空间地址 (wsdl文档中的targetNamespace)
      // 2.localPart - 服务视图名 (wsdl文档中operation的方法名称,例如<wsdl:operation name="getMobileCodeInfo">)
      QName qname = new QName("http://localhost:8080/", "Calibration");
      // 调用方法一 传递参数,调用服务,获取服务返回结果集
      OMElement element = serviceClient.invokeBlocking(qname, parameters);
      System.out.println(element);
      /*
       * 值得注意的是,返回结果就是一段由OMElement对象封装的xml字符串。
       * 我们可以对之灵活应用,下面我取第一个元素值,并打印之。因为调用的方法返回一个结果
       */
      String result = element.getFirstElement().getText();
      System.out.println(result);

      // 调用方法二 getPrice方法并输出该方法的返回值
      // 指定方法返回值的数据类型的Class对象
      Class[] returnTypes = new Class[] {String.class};
      Object[] responseParam = serviceClient.invokeBlocking(qname, parameters, returnTypes);
      String r = (String) responseParam[0];
      System.out.println(r);

   } catch (AxisFault e) {
      e.printStackTrace();
   }
   return resultMap;
}


/**
 * 强制校时
 *
 * @param request
 * @param response
 * @return
 * @throws JsonProcessingException
 */
@RequestMapping(params = "act=compulsorySchoolTimeTwo", method = {
      RequestMethod.POST, RequestMethod.GET
})
public Map<String, Object> compulsorySchoolTimeTwo(HttpServletRequest request, HttpServletResponse response) {
   Map<String, Object> resultMap = null;

   try {
      ServiceClient serviceClient = new ServiceClient();
      //创建服务地址WebService的URL,注意不是WSDL的URL
      String url = "http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx";
      EndpointReference targetEPR = new EndpointReference(url);
      Options options = serviceClient.getOptions();
      options.setTo(targetEPR);
      //确定调用方法(wsdl 命名空间地址 (wsdl文档中的targetNamespace) 和 方法名称 的组合)
      options.setAction("http://WebXml.com.cn/getMobileCodeInfo");

      OMFactory fac = OMAbstractFactory.getOMFactory();
      /*
       * 指定命名空间,参数:
       * uri--即为wsdl文档的targetNamespace,命名空间
       * perfix--可不填
       */
      OMNamespace omNs = fac.createOMNamespace("http://WebXml.com.cn/", "");
      // 指定方法
      OMElement method = fac.createOMElement("getMobileCodeInfo", omNs);
      // 指定方法的参数
      OMElement mobileCode = fac.createOMElement("mobileCode", omNs);
      mobileCode.setText("15932582632");
      OMElement userID = fac.createOMElement("userID", omNs);
      userID.setText("");
      method.addChild(mobileCode);
      method.addChild(userID);
      method.build();

      //远程调用web服务
      OMElement result = serviceClient.sendReceive(method);
      System.out.println(result);

   } catch (AxisFault axisFault) {
      axisFault.printStackTrace();
   }
   return resultMap;
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值