背景:当前的 Grails 应用程序必须与来自第三方供应商的“旧版”Web 服务进行交互 - (systinet) 使用 Apache CXF Wsdl2Java 工具来生成复杂的类型和服务接口。到目前为止非常标准的东西,这在 Java中非常有效。
在编写了一些测试类和 main() 方法来练习 Java 代码,并在上面提供了一个简化接口的薄层之后,我想从 Grails 应用程序中调用这段代码。具体来说,Grails 控制器、服务、石英作业等。然而,这就是事情变得有趣的地方。
来自 Grails CXF 插件的第一个堆栈跟踪导致 FileNotFoundException。除了不需要加载 WSDL 定义之外——因为我已经成功运行了 CXF 的 Wsdl2Java 工具,所以这里似乎缺少一些东西。尝试用 file:/// url*** 替换 WSDL 并得到另一个例外。
在这一切结束时——删除任何类型的插件,我手动使用 CXF 依赖项重新配置项目**,现在得到一个 MarshallingException,主要来自 CXF 生成的代码!顺便说一句,它可以从 Java 类中完美执行。
我敢肯定有人在您的 Grails 集成中遇到过这个问题。一如既往,我们非常感谢您的指导!
1)为什么在 Grails 应用程序中,运行时会尝试解析 wsdl ?另外,请注意 JDK 版本是相同的 java 版本“1.6.0_12”。
2)任何人都可以建议的任何 CLASSPATH 解决方法?我想另一种方法是使用 GroovyWS 重写 Java 中间层调用,但这将是一项相当大的工作——考虑到服务的数量和供应商已经采用的自定义类型。
static {
URL url = null;
try {
url = new URL("http://mydevhost:9080/wasp/bmc-security/ctsa/person");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from server");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
/* 静态 { URL url = null; 尝试 { url = new URL("file:///C:/Projects/beta/workspace/reqmgr3/wsdl/Person.wsdl" ); url.getPath(); } catch (MalformedURLException e) { System.err.println("无法从文件系统初始化默认 wsdl"); // e.printStackTrace(); } WSDL_LOCATION = 网址;} */
`
****堆栈痕迹
信息:没有为 Conduit 配置信任决策者...... 2010 年 8 月 11 日下午 6:26:16 org.apache.cxf.transport.http.HTTPConduit finalizeConfig 信息:没有为 Conduit 配置基本身份验证供应商...... 2010 年 8 月 11 日下午 6:26:16 org.apache.cxf.transport.http.HTTPConduit 准备信息:分块设置为 2048。2010 年 8 月 11 日下午 6:26:16 org.apache.cxf.phase.PhaseInterceptorChain doIntercept INFO:拦截器有抛出的异常,现在展开 org.apache.cxf.interceptor.Fault: Marshalling Error: com.systinet.wsdl.com.bmc.security.ess.webservice.holder.ArrayOfLog inPairHolder 在 org.apache.cxf 的上下文中是未知的.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:132) 在 org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:42) 在 org.apache.cxf.jaxb.io.XMLStreamDataWriter。在 org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:148) 在 org.apache.cxf.handleMessage(BareOutInterceptor.java:73) 在 org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:73) 写入(XMLStreamDataWriter.java:30) .cxf.endpoint.ClientImpl.invoke(ClientImpl.java:215) 在 org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73) 在 org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java :122) 在 $Proxy44.login(Unknown Source) ... ... 2 更多java:215) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:122) at $Proxy44.login(Unknown Source ) ... ... 2 更多java:215) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:122) at $Proxy44.login(Unknown Source ) ... ... 2 更多
8 月 15 日更新:
出于模块化和权宜之计,决定将此代码放入单独的 WAR 项目中,该项目将提供其 ltd。服务,而不是暴露原始的供应商 Web 服务,这太笨拙了。
这个项目将是纯 Java 并利用 Metro 2.0.1 运行时,大约 16mb。
在清除 lib 和 src/java 文件夹之后,现在可以从 Grails 调用基于 Java 的中间件服务——基本上只是安装了 ws-client 插件并设置了本地服务,如下所示:
import groovyx.net.ws.WSClient
import org.grails.plugins.wsclient.service.WebService
class LocalPersonService {
WebService webService
groovyx.net.ws.WSClient _proxy
static final String PERSON_WSDL_URL = "http://localhost:9090/pri/PersonServicePort?wsdl"
def transactional = false
def getPersonDetails( String customerId, User userAccount, String userCredential ) {
// must cache the proxy
if ( _proxy == null ) {
print( "init proxy. Parsing wsdl..." )
try {
_proxy = webService.getClient(PERSON_WSDL_URL)
}
catch ( Throwable tr ) { println( tr.getMessage() ) }
}
// method shall return a (com.siventures.example.service.PersonDetails)
return _proxy.getPersonDetails( customerId, userAccount, userCredential, ... )
}