消费SOAP Web服务 - Java VS PHP
一般问题:消费SOAP Web服务 - Java VS PHP
我们正在我们公司推出一个名为ServiceNow的新ITSM Toolsuite。 ServiceNow提供了很多不错的开箱即用Web服务。 当前我们正在实现一些与其他interal系统的接口,并且我们使用这些Webservices来使用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服务消费。所以我决定走下去。
- 安装Apache Axis
-
开放的cygwin或cmd并从WSDL生成类..跆拳道?做什么的?
$ ./wsdl2java.sh -uri https://blah.com/incident.do?WSDL
复制生成的类Java项目在Eclipse。
- 使用此类:
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?
首先:我完全同意。我在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系统的许多缺陷。
嗨,我遇到了同样的问题,我发现Json Service作为替代解决方案。但是,如果你有,可以提供一些示例代码片段吗? –
如果您使用的是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>
我在我工作的公司使用PHP大量使用Soap服务,而且我总是建议为请求和响应数据结构生成类。否则,您将很容易迷路--PHP不保留原始XML结构的任何遗留物,它将全部转换为数组和stdClass对象。
从WSDL描述中获取创建的类在PHP中并不是那么容易,因为只有几个脚本可以做到这一点 - 而且它们都有它们的缺点,当涉及到WSDL文件时,它们利用了更加模糊的部分SOAP标准。之后,你不知何故必须让这些类可用于你的PHP脚本。如果这对你来说很难,这是一个组织不太好的代码库的标志。借助自动加载功能,它就像魅力一样。
但是,这一步对PHP完全是可选的。如果只使用一个Soap服务,它可能没有区别。
我还试图从Eclipse使用Eclipse访问ServiceNow,在我看来Axis2方法过分限制了ServiceNow设计API的方式,所以我编写了自己的包来动态使用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"));
}
几个关于这个代码的东西:
- 我使用运行时确认,而不是构建时验证。如果您错误地键入getField(“shortdescription”),则代码将引发InvalidFieldNameException。
- 查询不受ServiceNow正常的250条记录限制的约束,因为BulkFetcher在内部根据需要循环执行尽可能多的Web Service调用以检索所有数据。
我喜欢Netbeans的网络服务向导,(它这个最适合你),但我真的没有广泛使用它们。 – madth3
@felixsigl希望你在这个时候为你的问题找到了解决方案。你能分享一下吗? 因为我也遇到了同样的问题,我发现Json Service作为替代解决方案。但是我在连接到ServiceNow时遇到了一些问题。如果你有一些代码片段,这将是有帮助的。 –