2

一个普遍的问题:

我们正在我们公司推出一个名为 ServiceNow 的新 ITSM 工具套件。ServiceNow 提供了很多很好的开箱即用的 Web 服务。目前我们正在实现一些与其他内部系统的接口,我们使用这些 Web 服务来使用 Servicenow 的数据。

我们是如何在PHP中做到的:

<?php
$credentials = array('login'=>'user', 'password'=>'pass');
$client = new SoapClient("https://blah.com/incident.do?WSDL", $credentials);
$params = array('param1' => 'value1', 'param1' => 'value1');
$result = $client->__soapCall('getRecords', array('parameters' => $params));
// result array stored in $result->getRecordsResult
?>

就是这样!5 分钟的工作,美丽而简单——从我的角度来看。

好的,现在在Java中也一样:

我做了一些研究,似乎每个人都在使用 Apache Axis2 来使用 Java 中的 Web 服务。所以我决定走这条路。

  1. 安装 Apache Axis
  2. 打开 cygwin 或 cmd 并从 WSDL 生成类 .. WTF?做什么的?

    $ ./wsdl2java.sh -uri https://blah.com/incident.do?WSDL

  3. 将生成的类复制到 Eclipse 中的 Java 项目。

  4. 使用此类:
ServiceNow_incidentStub proxy = new ServiceNow_incidentStub();

proxy._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
ServiceNow_incidentStub.GetRecords defectsGetRecords = new ServiceNow_incidentStub.GetRecords();
ServiceNow_incidentStub.GetRecordsResponse defectsResult = new ServiceNow_incidentStub.GetRecordsResponse();
proxy._getServiceClient().getOptions().setManageSession(true);
HttpTransportProperties.Authenticator basicAuthentication = new HttpTransportProperties.Authenticator();
basicAuthentication.setUsername("user");
basicAuthentication.setPassword("pass");
proxy._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, basicAuthentication);
defectsResult = proxy.getRecords(defectsGetRecords);
com.service_now.www.ServiceNow_incidentStub.GetRecordsResult_type0[] defects = defectsResult.getGetRecordsResult();

for (int j=0; j < defects.length; j++) {
    // do something
}

它的工作,但我认为这种方式非常复杂.. 每次 wsdl 中的某些内容发生变化 - 我必须使用轴重新编译它们。无法在全局范围内配置诸如 Soap-endpoint 之类的东西。

在 Java 中有没有更简单的方法来使用 WSDL 来使用 SOAP?

4

4 回答 4

2

首先:我完全同意。我在 Web 服务和 ServiceNow 方面做了很多工作,使用 Java 和/或 .Net 与使用脚本语言(我通常使用 Perl 编写脚本)有很大不同。固有的问题在于 WSDL 不应该经常更改,尤其是在生产中。Java 和 .Net 中的想法是让这些存根类进行编译时错误检查。

如果您目前处于 Ph1 并且尚未部署 Prod,那么您应该真正了解 WSDL 的更改频率。然后从那里决定使用哪种技术。好消息是,即使 WSDL 发生更改,将数据发布到实例 - 几乎所有字段都是可选的。因此,如果添加一个新字段,这没什么大不了的。当返回数据时(大多数情况下)会出现问题,因为如果返回的 XML 不在预期的结构中,java 和 .net 会多次抛出异常。

许多人做的一件事是将模块设置为 CMDB 中的 CI,并通过更改请求模块维护他们的 ServiceNow 实例。这样,您的 java 应用程序将成为您正在查询的任何模块/表的下游 CI,并且当放入 CR 以修改该表时,将立即知道这也会对您的内部应用程序产生影响。

不幸的是,您是对的,这是对不同语言的权衡,根据我的经验,我们几乎无法改变这一点。

我忘了添加一件事,您的另一种选择是改用 JSON 服务。这将允许您向 SNC 实例发出原始请求,然后使用 JSON 解析器“即时”为您解析该数据。它消除了编译时检查,但也消除了 SOAP 系统的许多缺陷。

于 2012-12-20T08:23:07.150 回答
1

如果您使用的是 maven,请尝试使用此插件。

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>axistools-maven-plugin</artifactId>
    <version>1.4</version>
    <configuration>
        <urls>
                 <url>https://blah.com/incident.do?WSDL</url>
            </urls>
              <packageSpace>your.destination.package</packageSpace>
              <serverSide>true</serverSide>
              <outputDirectory>src/main/java</outputDirectory>
    </configuration>
    <executions>
         <execution>
            <goals><goal>wsdl2java</goal></goals>
         </execution>
    </executions>
</plugin>
于 2012-12-14T13:38:11.923 回答
1

我还尝试使用 Eclipse 从 Java 访问 ServiceNow,在我看来,考虑到 ServiceNow 如何设计他们的 API,Axis2 方法的限制过于严格,所以我编写了自己的包来使用 JDOM 动态生成 SOAP 调用。以下是代码的示例:

Instance instance = new Instance("https://blah.service-now.com", "username", "password");
GlideFilter filter = new GlideFilter("category=network^active=true");        
GlideRecordIterator iter = instance.table("incident").
    bulkFetcher().setFilter(filter).getAllRecords().iterator();
while (iter.hasNext()) {
    GlideRecord rec = iter.next();
    System.out.println(
        rec.getField("number") + " " + rec.getField("short_description"));
}           

关于这段代码的几件事:

  1. 我使用运行时验证而不是构建时验证。如果您错误地键入 getField("shortdescription"),代码将引发 InvalidFieldNameException。
  2. 查询不受 ServiceNow 的正常 250 条记录限制的约束,因为 BulkFetcher 在内部循环,根据需要进行尽可能多的 Web 服务调用以检索所有数据。

包源代码位于https://sourceforge.net/projects/servicenowpump/

于 2013-05-13T21:21:58.393 回答
0

我在我工作的公司中使用 PHP 使用了很多 Soap 服务,并且我总是建议为请求和响应数据结构生成类。否则你很容易迷失方向——PHP 不会保留原始 XML 结构的任何残留物,它将全部转换为数组和 stdClass 对象。

在 PHP 中获取从 WSDL 描述创建的类并不是那么容易,因为只有少数几个脚本可以做到这一点 - 当涉及到 WSDL 文件时,它们都有自己的缺点,因为它们使用了 SOAP 标准中更晦涩的部分。之后,您必须以某种方式使这些类可用于您的 PHP 脚本。如果这对您来说很难,则表明代码库组织得不太好。使用自动加载功能,它就像一个魅力。

但是,是的,这一步对于 PHP 来说是完全可选的。如果只使用一种 Soap 服务,它可能没有任何区别。

于 2012-12-15T17:55:35.157 回答