サーバーにWeb APIがないが、非常に必要な場合

開発者の生活には、「本当にしたいのにできない」という状況がよくあります。 そして、この問題は、私たちの国のすべてのものと同じように、非常に頻繁に解決されます。 今日は、このAPIが提供しないWebプロジェクト用の独立したAPIを作成した私の経験についてお話したいと思います。 この記事は、JavaまたはSolarisの開発者だけでなく、さまざまなサービスを統合する問題に直面しているすべての人々にとって有用です。



少し前まで、SourceJuicerプロジェクト( http://jucr.opensolaris.org/ )がすべての開発者向けに開かれました。これにより、OpenSolaris用のプロジェクトを公開し、それらを構築して公開リポジトリに公開できます。 プロジェクトの説明は、仕様ファイル( http://jucr.opensolaris.org/help/spec_file )の形式で作成されます。プロジェクトファイルには、プロジェクトの属性、収集方法、ソースコードのダウンロード元、配布されたライセンスなどが記載されています。 アセンブリに必要なすべてのファイルはサーバーにアップロードされ、レビュー後にアセンブルされてリポジトリにアップロードされます。 すべてがクールに思えますが、キャッチは何ですか? そして、問題は、プロジェクトを作成し、Webインターフェースからのみファイルをアップロードまたは更新できることです。 原則として、小規模なプロジェクトではそれほど致命的ではありませんが、すでに10個のファイルがあるため、このダウンロードと更新のプロセスは少し面倒です。



さらに、このようなロードシステムは継続的インテグレーションには絶対に適していません。つまり、本質的にSourceJuicerが作成されました。 したがって、このサービス(または他のサービス)を可能な限り効率的に使用する方法をさらに説明します。これにより、将来、興味深いアイデアが生まれます。







どこから始めますか? マスターは常にツールによって認識され、他の人のWebサイトを探索する人はFirebugです。 原則として、任意のシステムで作業するユーザーのシナリオは次のようになります



  1. 認定を実施します。
  2. 目的のリンクに移動します。
  3. フォームフィールドに入力します。
  4. アクションを確認します。
  5. 必要に応じて手順2を繰り返します。




サイトのWeb APIを作成するには、これらのユーザーアクションをできるだけ正確に記述し、必要に応じて実行する必要があります。 たとえば、承認とは、フォームに応じて正しいCookieを受信することです。 したがって、Firebug( http://getfirebug.com/ )およびFirecookie( http://www.softwareishard.com/blog/firecookie/ )がインストールされたFirefoxを使用し、認証ページに移動して、認証が成功したときに設定されたCookieを確認します。



原則として、認可中にラベルが発行されます-「セッション番号」(トークン)。リクエスト中に変更されません。 「jsessionid」、「phpsession」、「OSS」などです。 ただし、リクエストが繰り返されるたびにCookieを変更するオプションもあるため、検討する価値があります。 SourceJuicerでの承認の場合、3つのCookieが使用されるため、要求されたときに3つすべてを保存および送信する必要があります。 また、承認フォームのあるページが常に旅行の出発点ではないことを忘れないでください。多くの場合、セッションを初期化するには、サーバーまたはユーザーの開始ページに移動する必要があります。



何をする必要があるかはわかっているので、コードでそれをどのように記述するかを見てみましょう。 このような素晴らしいHttpUnitライブラリ( http://httpunit.sourceforge.net/ )を使用すると、Webインターフェイスをテストできます。リンクをたどり、フォームを送信し、テーブルの内容をチェックし、多くの興味深いことができます。 しかし今では、httpリクエストを送信し、レスポンスを処理する簡単な方法として興味を持っています。 このライブラリを使用するには、htmlパーサーとjavascriptインタープリターを接続する必要があります。 nekohtml( http://nekohtml.sourceforge.net/ )とMozilla rhino( http://www.mozilla.org/rhino/ )を使用しました-ただし、xercesへの依存度が高いため、nekoは本番環境にはお勧めしません。



そのため、ページに移動し、Cookieを取得してフォームを送信する必要があります。 このコードは次のようになります



wc.getResponse(JUICER_HOME_URL); // Creating new jsession

wc.getResponse(JUICER_AUTH_URL); // Go to login



WebResponse response = wc.getResponse(AUTH_URL); // Load login form

WebForm loginForm = null ;



for (WebForm form : response.getForms()) {

if (form.getAction().equals( "/login.action" )) {

loginForm = form;



break ;

}

}



loginForm.setParameter( "userName" , username);

loginForm.setParameter( "password" , password);



loginResult = loginForm.submit(); // Submit user name and password



* This source code was highlighted with Source Code Highlighter .








SourceJuicerでプロジェクトを更新するときの次のオプションでは、プロジェクトをビルドするためにすべてのファイルが既に必要なわけではありません。 したがって、どのファイルが古くなっているかを確認して削除する必要があります。 これは、次のようにWebインターフェイスを介して解決できます。既存のプロジェクトのページが開き、最初のテーブルにファイルのリストがあり、[削除]ボタンが各ファイルの反対側にあります。 ボタンをクリックすると、確認フォームが表示され、「確認」をクリックするとファイルが削除されます。



それがすべてコードでどのように見えるか



WebResponse response = conversation.getResponse( String .format(JUICER_SUBMISSION_MASK, submissionId));

WebTable fileList = response.getTableStartingWith( "Summary" ). // Summary

getTableCell(2, 1). //

getTables()[0]; //



Collection< String > forDelete = new ArrayList < String >();



for ( int i = 0; i < fileList.getRowCount(); i++) {

WebLink link = fileList.getTableCell(i, 0).getLinks()[0]; //



String fullName = link.getText().replaceAll( "\\s+" , "" );

String fileName = fullName.replaceAll( "[^/]+/([^/]+)" , "$1" );

SubmitType type = detectType(fullName);



if (existFileInSubmission(files, type, fileName) == null ) {

String fileId = fileList.getTableCell(i, 1).getForms()[0].getParameterValue( "file_id" ); // id



forDelete.add(fileId);



debug( "Need to delete file [%s]" , fullName);

}

}



for ( String fileId : forDelete) {

PostMethodWebRequest post = new PostMethodWebRequest(

String .format(JUICER_DELETE_MASK, submissionId),

true

);



post.setParameter( "delete_file" , "Delete File" );

post.setParameter( "file_id" , fileId);



WebResponse confirmResponse = conversation.getResponse(post); //



WebForm form = confirmResponse.getForms()[0];

SubmitButton confirm = form.getSubmitButtons()[1]; // Confirm ...



WebResponse r = form.submit(confirm); // ...



}



* This source code was highlighted with Source Code Highlighter .








そのため、単純なCookie操作、リクエスト、およびHTML解析の助けを借りて、作業バージョンのapi( http://bitbucket.org/abashev/pusher/src/ade4e90f01a9/src/main/java/org/bitbucket/pusher/api/ SourceJuicerAPI.java )、サービス開発者ではなく、私たちにとって便利なため使用できます。



プロジェクトの完全版はこちらにあります-bitbucket.org/abashev/pusher



喜んであなたの質問や希望に耳を傾けます。






All Articles