背景: 現在の Grails アプリケーションは、サードパーティ ベンダーの「レガシー」Web サービスと対話する必要があります - (systinet) Apache CXF Wsdl2Java ツールを使用して、複雑な型とサービス インターフェイスを生成しました。これまでのところかなり標準的なもので、これは Java から完全に機能します。
Java コードを実行するためのいくつかのテスト クラスと main() メソッドを作成し、簡素化されたインターフェイスのために上に薄いレイヤーを提供した後、Grails アプリからこのコードを呼び出したいと思いました。具体的には、Grails コントローラー、サービス、Quartz ジョブなどです。しかし、これが興味深いところです。
Grails CXF プラグインからの最初のスタック トレースで、FileNotFoundException が発生していました。WSDL 定義をロードする必要がないだけでなく、CXF の Wsdl2Java ツールを既に正常に実行しているため、ここで何かが欠けているようです。WSDL を file:/// url*** に置き換えようとしたところ、別の例外が発生しました。
このすべての終わりに -- あらゆる種類のプラグインを削除し、手動で CXF 依存関係を使用してプロジェクトを再構成し**、CXF によって生成されたコードから本質的に MarshallingException を取得しました! ちなみに、これは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 = 新しい URL( "file:///C:/Projects/beta/workspace/reqmgr3/wsdl/Person.wsdl" ); を試してください。url.getPath(); } catch (MalformedURLException e) { System.err.println("ファイル システムからデフォルト wsdl を初期化できません"); // e.printStackTrace(); } WSDL_LOCATION = URL; } */
`
****スタックトレース
情報: Conduit 用に構成された Trust Decider がありません... 2010 年 8 月 11 日 6:26:16 PM org.apache.cxf.transport.http.HTTPConduit finalizeConfig 情報: Conduit 用に構成された Basic Auth Supplier がありません... 2010 年 8 月 11 日2010 年 8 月 11 日 6:26:16 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept INFO: Interceptor has例外がスローされました。現在巻き戻し中です.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:132) org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:42) at org.apache.cxf.jaxb.io.XMLStreamDataWriter.write(XMLStreamDataWriter.java:30) at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:73) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:148) at org.apache .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) at $Proxy44.login(Unknown Source) ... ... 2 つ以上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) org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73) で org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:122) で $Proxy44.login(Unknown Source ) ... ... 2以上
8月15日更新:
モジュール性と利便性の両方から、このコードを別の WAR プロジェクトに入れることを決定しました。扱いにくい元のベンダーの Web サービスを公開するのではなく、サービスを提供します。
このプロジェクトはピュア Java で、約 16 MB の Metro 2.0.1 ランタイムを利用します。
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, ... )
}