axis 1.4ノートを使う(3)


3.2クライアントプログラムの開発
3.2.1 java 2 WSDL 
 
このツールはサーバーの端の人が使うべきものです。ここに置いておくのは主に説明のためです。このツールを起動すると、javaクラスに応じて、対応するwsdlファイルを生成してリリースすることができます。以下はバッチファイルです。保存できます。ちょっと変更してもいいです。
set Axis_Lib=D:\JavaTools\axis-1_4\lib    
set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib%
%Java_Cmd% org.apache.axis.wsdl.Java2WSDL  
   -osn_advanceSearch.wsdl 
   -lhttp://localhost:8080/axis/services/SN_AdvanceSearch 
   -n"urn:BeanService" 
   -p"cn.edu.tju.ikse.sn.advancedSearch" "urn:BeanService"    cn.edu.tju.ikse.sn.advancedSearch.SemanticQueryOperate
pause
 -O:生成したwsdlファイル名を指定します。
-l:生成サービスのアクセスアドレスを指定します。
-n:名前空間を指定します。
-p:名前空間とカバンの対応関係を指定します。
最後に具体的なjavaクラスを指定します。つまり、発表するクラスです。
このツールが最も適している環境:サービス端末は業務の必要に応じて露出したインターフェースを書き終わったら、このツールでwsdlファイルを生成できます。自分でwsdlファイルを書く必要がなくて、理論的にこのwsdl文書に基づいてこのサービスを発表することができます。クライアントは一般的にこの方法を起動しません。クライアントは普通書類を手に入れられません。ここに置くと、このような使いやすいツールがあるということです。
 
3.2.2 WSDL 2 java
 
      このツールはwsdlファイルから対応するコールクラスを生成します。これはクライアントで有用です。サービスからwsdlファイルを入手するしかないです。コードやクラスのファイルを入手できない場合は、それを頼りにしなければなりません。このツールはwsdlドキュメントの定義に基づいて、いくつかの対応するクラスを生成します。複雑なタイプの定義のように、対応するjavaBeanを生成します。
WSDL 2 Java.batを編集します。Axis_Libはaxis.jar経路である。内容は以下の通りです
set Axis_Lib=D:\JavaTools\axis-1_4\lib    
set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib%    
set Output_Path=D:\JavaTools\eclipse3.2\workplace\axisTest\src   
set Package=cn.edu.tju.ikse.sn.advancedSearch  
%Java_Cmd% org.apache.axis.wsdl.WSDL2Java -o%Output_Path% -p%Package% http://localhost:8080/axis/services/SN_AdvanceSearch?wsdl
pause
 
説明はいらないでしょう。WSDL 2 Javaを呼び出してサービスに応じて対応するインターフェースを生成します。
      最後から二番目の行は、wsdl 2 javaというツールを使って、最後にwsdlファイルの位置を指定します。このファイルはローカルのwsdlファイルでもいいし、ネット上のwsdlファイルでもいいです。
      次の3行目を説明します。3行目は私のクライアントプロジェクトのソースファイルのパスです。このようにツールによって生成されたコードは直接プロジェクトに追加されます。コピー貼り付けの手間を省きます。次の項目を更新します。パッケージでcn.edu.tju.ikese.sn.advancendSearch  下に六つのjavaファイルが見えます。
AdvianceSearch.java/カスタムタイプは、wsdlの複雑なタイプの定義に対応するjavaBenを生成します。
Serviceinfo.java/これもカスタムタイプです。最初はこの人たちが生まれませんでした。後の注意事項には原因が述べられます。
Semantic Query Operate.java,/これはインタフェースで、サーバーの端が何ができるかを説明します。wsdlに対応するwsdl:portType
Semantic Query Operate Service.java,これはインターフェイスです。
Semantic Query Operate ServiceLocator.javaは、Semantic QueryOperate Serviceインターフェースを実現しました。このような役割は直接サーバと通信して、サーバー端との接続を確立して、stubとサーバと通信することができます。
SN_AdvincSearch SoappBindingStub.java.このクラスはSemantic QueryOperateインターフェースを実現しました。サーバとしてクライアントに保存されています。つまりstubです。クライアントでは、サーバへのすべての呼び出しは、本質的にstubへの呼び出しです。
 
3.2.3クライアントコード
 
クライアントコードには主に2つの方法があります。
  • 第1の方法は、wsdl 2 javaによって生成されたstubクラスを利用して呼び出しを行うことであり、この方法の利点はコールが簡単であり、サービス端末のサポートが不要である
  • である。
  • の第二の方法は、stubクラスを介して呼び出さないことであり、この方法は、ユーザによって呼び出されたすべてのパラメータを制御する。
  • 実際に使う時は第一の方式を多く使うべきです。コードは簡単に書きます。それぞれについて説明します。
    まず第二の方法を話しましょう。コードを見てください。
    public static void testadvancesearch() {
    		//        
    		String url = "http://127.0.0.1:8989/axis/services/SN_AdvanceSearch";
    		//            
    		AdvanceSearch search = new AdvanceSearch();
    		search.setDomain("Biology");
    		search.setServiceName("getENTRYbyScientificName");//getENTRYbyScientificName
    
    		try {
    			Service service = new Service();//      
    			Call call = (Call) service.createCall();
    			//  javaBean    server-config.wsdd    
    			QName qn = new QName("urn:BeanService", "Serviceinfo");
    			call.registerTypeMapping(Serviceinfo.class, qn,
    					new org.apache.axis.encoding.ser.BeanSerializerFactory(
    							Serviceinfo.class, qn),
    					new org.apache.axis.encoding.ser.BeanDeserializerFactory(
    							Serviceinfo.class, qn));
    			//    */			
    			call.setTargetEndpointAddress(new java.net.URL(url));
    			//        
    			call.setOperationName(new QName("SemanticQueryOperate",
    					"getAdvancedSearchArrayList"));
    			//      
    			//call.setReturnClass(ArrayList.class);	//call.invoke(new Object[]{"haha"});
    			//      
    			//call.addParameter("userpara", XMLType.XSD_ANYTYPE, ParameterMode.IN);			
    			//System.out.println(new Object[]{userPar});
    			//    
    			Object[] result = (Object[]) call.invoke(new Object[] { search });
    			if (result != null && result.length > 0) {
    				for (int i = 0; i < result.length; i++) {
    					Serviceinfo serviceinfo = (Serviceinfo) result[i];
    					System.out.println(serviceinfo.getCatagoryName()
    							+ serviceinfo.getAffiliation());
    				}
    			}
    
    		} catch (ServiceException e) {
    			e.printStackTrace();
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		} catch (RemoteException e) {
    			e.printStackTrace();
    		}
    	}
     
     上のコードはもう注釈されました。具体的に説明しません。
    第一の方式の呼び出しを見てください。
    public static void testadvancesearchstub() throws ServiceException {
    		//          
    		SemanticQueryOperateService service = new SemanticQueryOperateServiceLocator();
    		
    		SemanticQueryOperate client = service.getSN_AdvanceSearch();
    		//         
    		AdvanceSearch search = new AdvanceSearch();
    		search.setDomain("Biology");
    		search.setServiceName("dna");//getENTRYbyScientificName		
    		Object[] retValue = null;
    		try {
    			//    ,    
    			retValue = client.getAdvancedSearchArrayList(search);
    			System.out.println("start");
    			if (retValue != null && retValue.length > 0) {
    				for (int i = 0; i < retValue.length; i++) {
    					Serviceinfo serviceinfo = (Serviceinfo) retValue[i];
    					System.out.println(serviceinfo.getCatagoryName()
    							+ serviceinfo.getAffiliation());
    				}
    			}
    		} catch (RemoteException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
     コードによって、最初の方法は比較的簡単で、構成と呼び出しを分離したことが分かります。具体的には言いませんが、基本的にコードを見て、どういう意味か分かります。このような方式の利点と注意すべき点を次に述べる。