使用SOAP Webservice - Java VS PHP

时间:2012-12-14 13:12:12

标签: java php web-services soap servicenow

一般性问题:

我们正在我们公司推出名为ServiceNow的新ITSM Toolsuite。 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 Project。

  4. 使用此类:
  5. 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 个答案:

答案 0 :(得分:2)

首先:我完全同意。我在Web Services和ServiceNow上做了很多工作,使用Java和/或.Net与使用脚本语言(我通常使用Perl脚本)完全不同。固有的问题在于WSDL不应该经常改变,特别是在生产中。 Java和.Net中的想法是你得到这些存根类来进行编译时错误检查。

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

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

不幸的是你是对的,这是与不同语言的权衡,根据我的经验,我们无法改变这种情况。

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

答案 1 :(得分: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>

答案 2 :(得分: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服务调用以检索所有数据。
  3. 包源代码位于https://sourceforge.net/projects/servicenowpump/

答案 3 :(得分:0)

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

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

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