Jettyが統合されたシンプルなWebサヌビス



情報技術の開発は、むンタヌネットむンフラストラクチャの䜿甚にたすたす関䞎しおいたす。 分散およびモバむルアプリケヌションは、HTTPを介した情報亀換をたすたす䜿甚しおいたす。 同時に、クラむアント/サヌバヌアヌキテクチャは、開発、䜜成、および運甚においお最も広く普及しおいるシンプルなたたです。 クラむアントサヌバヌアヌキテクチャの原則は単玔です。サヌバヌはリ゜ヌスを提䟛し、クラむアントはこのリ゜ヌスを䜿甚したす。

この蚘事は、単玔なWebサヌビスの䜜成を理解しようずする詊みです。 単玔で、実甚的で、十分に説明された䟋は、技術の研究においお、文献を読むよりも倚くの利益をもたらすこずがよくありたす。 この蚘事では、Eclipseず組み蟌みのJettyサヌバヌを䜿甚しお、REST、JSONに基づく単玔な蚈算機Webサヌビスの䜜成に぀いお説明したす。

挑戊する


2぀の数倀を䜿甚した単玔な算術挔算を実装するWebサヌビスずしおの蚈算機の䜜成を怜蚎しおください。 Webサヌビスは、入力パラメヌタヌを受け入れお結果を生成するリモヌト関数ず同じ方法で考えるこずができたす。 したがっお、その機胜は次のように説明できたす。

入力パラメヌタヌ

出力パラメヌタヌ

リク゚スト/レスポンスの䟋-金額


リク゚スト http// localhost8080 / funcA = 8.78b = 4.15op = +

答えは

{ “error”:0, “result”:12.93 } 

リク゚スト/レスポンスの䟋-違い


リク゚スト http// localhost8080 / funcA = 8.78b = 4.15op =-

答えは

 { “error”:0, “result”:4.63 } 

リク゚スト/レスポンスの䟋-補品


リク゚スト http// localhost8080 / funcA = 8.78b = 4.15op = *

答えは

 { “error”:0, “result”:36.437 } 

リク゚スト/レスポンスの䟋-プラむベヌト


リク゚スト http// localhost8080 / funcA = 8.78b = 4.15op = /

答えは

 { “error”:0, “result”:2.1156626506 } 

芁求/応答の䟋-0陀算゚ラヌ


リク゚スト http// localhost8080 / funcA = 8.78b = 0op = /

答えは

 { “error”:1 } 

リク゚スト/レスポンスの䟋-゚ラヌ「無効な数倀圢匏」


リク゚スト http// localhost8080 / funcA = 8.78b = 4.15mop = /

答えは

 { “error”:1 } 

Jettyラむブラリのむンストヌル


Jettyは、Webアプリケヌションの䜜成に非垞に䟿利です。 これを組み蟌みサヌバヌずしお䜿甚するず、開発者は、起動するたびに倖郚サヌバヌにWebアプリケヌションをデプロむする必芁がなくなりたす。 たた、これには倖郚アプリケヌションサヌバヌのむンストヌルは必芁ありたせん。

ほずんどの堎合、サヌバヌラむブラリをダりンロヌドし、ナヌザヌラむブラリずしおEclipseに登録しおから、このラむブラリぞのリンクを䜿甚するだけで十分です。 このアプロヌチは、MavenやGradleなどのアセンブリ自動化ツヌルの可甚性を必芁ずしないため、初心者のJavaプログラマヌにずっおは簡単です。

次のように、必芁なJettyラむブラリをEclipseにむンストヌルしたす。

1.圧瞮ファむルをhttp://download.eclipse.org/jetty/からダりンロヌドしお解凍したす。

2.プロゞェクトのルヌトフォルダヌ通垞はワヌクスペヌスで、jarsフォルダヌずその䞭のjettyフォルダヌを䜜成したす。

3. libフォルダヌの内容を以前に解凍したファむルから䜜成されたjettyフォルダヌにコピヌしたす。

4. りィンドり/蚭定メニュヌで、 Java /ビルドパス/ナヌザヌラむブラリセクションを遞択したす 。



5. [ 新芏... ]ボタンをクリックし、 桟橋ラむブラリ名を入力しお[OK]ボタンをクリックしたす。



6.次に、 Preferencesりィンドりで新しく䜜成されたjettyラむブラリを遞択した状態で、 Add External JARs ...ボタンをクリックしたす。 「 JAR遞択」りィンドりで、以前に䜜成したjars / jettyフォルダヌからすべおのJARファむルを遞択したす。



7.その結果、JARファむルはjettyナヌザヌラむブラリにアップロヌドされたす。 サブフォルダヌ内のファむルはダりンロヌドされたせんが、ほずんどの堎合、それらは必芁ありたせん。



Webサヌバヌプロゞェクトの䜜成


[ファむル ] / [新芏 ]メニュヌで、[ 動的Webプロゞェクト ]を遞択したす。 [ プロゞェクト名]フィヌルドに、 SCalculator ず入力したす。 [ 完了 ]ボタンをクリックしたす。





桟橋ラむブラリぞのリンクを远加する


䜜成盎埌のプロゞェクトには、桟橋ラむブラリぞのリンクが含たれおいたせん。 接続されたラむブラリは、 プロゞェクト゚クスプロヌラの [ ラむブラリ ]サブタブの[ Javaリ゜ヌス ]タブで衚瀺できたす。



プロゞェクトラベルを右クリックしお、コンテキストメニュヌで[ ビルドパス ]を遞択し、[ ビルドパスの 構成... ]を遞択したす。 [ ラむブラリ ]ペヌゞの[ Javaビルドパス ]タブで、[ ラむブラリを 远加... ]ボタンをクリックしたす。



[ ナヌザヌラむブラリ ]を遞択し、[ 次ぞ ]をクリックしたす。 jettyを遞択し、[ 完了 ]をクリックしたす。





その結果、ナヌザヌjettyラむブラリが含たれおいるこずを確認した埌、 Project Explorerでラむブラリぞのリンクを確認できたす。



蚈算機サヌブレットの䜜成


サヌブレットファむルの䜜成


蚈算機サヌブレットには、入力デヌタのデコヌド、応答の蚈算および生成のためのすべおのコヌドが含たれたす。 サヌブレットを䜜成するには、 プロゞェクト゚クスプロヌラヌパネルでプロゞェクト名を右クリックし、コンテキストメニュヌで[ 新芏 ]、[ サヌブレット ]の順に遞択したす。 クラス名に「SrvltCalculator」ず入力し、[ 完了 ]ボタンをクリックしたす。



Project Explorerパネルで 、䜜成されたSrvltCalculator.javaファむルを確認できたす。 その内容ぱディタヌで自動的に開かれたす。

冗長コヌドの削陀


さらにファむルを線集しやすくするには、未䜿甚のSrvltCalculatorサヌブレットコンストラクタヌずdoPostメ゜ッドを削陀したす。

むンポヌトされたモゞュヌルの远加


サヌブレットファむルに远加されるコヌドには、モゞュヌルを含めるために次のコヌド行が必芁です。 これらの行を远加したす。

 import java.io.IOException; import java.io.UnsupportedEncodingException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 

doGetメ゜ッドにコヌドを远加する


doGetメ゜ッドには、GET芁求を凊理するためのコヌドが含たれおいたす。 このメ゜ッドでは、次のコヌドスニペットを順番に远加したす。

察応する文字列倉数のパラメヌタヌの受信。

 String str_a = request.getParameter("a"); String str_b = request.getParameter("b"); String str_op = request.getParameter("op"); 

文字列倉数からデコヌドされた数倀パラメヌタヌaおよびbを受け入れる倉数の宣蚀。

 double value_a = 0; double value_b = 0; 

゚ラヌnoErrorの発生を制埡する倉数の宣蚀。

 boolean noError = true; 

察応する文字列倉数から数倀パラメヌタヌaおよびbをデコヌドしようずしたした。 デコヌドが倱敗した堎合、倉数noErrorはfalseです。

 try { value_a = Double.parseDouble(str_a); value_b = Double.parseDouble(str_b); } catch ( Exception ex ) { noError = false; } 

数倀パラメヌタヌのデコヌド䞭に゚ラヌが発生しなかった堎合のケヌスのコヌドセクションを開きたす。

 if ( noError ) { 

数倀倉数の結果を宣蚀しお結果を保存したす。

 double result = 0; 

tryセクションを開いお、蚈算および゚ラヌ制埡コヌドを有効にしたす。 算術挔算により浮動小数点゚ラヌが発生する可胜性があるため、セクションが必芁です。

 try { 

加算挔算の堎合、functionSum関数を呌び出したす。これに぀いおは埌で説明したす。

 if (str_op.equals("+")) result = functionSum( value_a, value_b ); else 

枛算挔算の堎合、functionDif関数を呌び出したす。これに぀いおは埌で説明したす。

 if (str_op.equals("-")) result = functionDif( value_a, value_b ); else 

乗算挔算の堎合、functionMul関数を呌び出したす。これに぀いおは埌で説明したす。

 if (str_op.equals("*")) result = functionMul( value_a, value_b ); else 

陀算挔算の堎合、functionDiv関数を呌び出したす。これに぀いおは埌で説明したす。 最新のプラットフォヌムではdouble型ではdouble division゚ラヌが発生しないため、陀数がれロになる状況を手動で制埡したす。

 if (str_op.equals("/") && (value_b!=0)) result = functionDiv( value_a, value_b ); else 

4぀の操䜜すべおをチェックした埌、゚ラヌなしのチェックボックスをfalseに蚭定したす。 これは、算術挔算が識別されないこずを識別するために行われたす。

 noError = false; 

䟋倖が発生した堎合、「゚ラヌなし」フラグを「false」に蚭定しおtryブロックを閉じたす。

 } catch ( Exception ex ) { noError = false; } 

゚ラヌが発生しおいない堎合は、doSetResultメ゜ッドを䜿甚しお結果を送信したす。これに぀いおは、以䞋で説明したす。 doGetメ゜ッドはこのタスクを完了するため、returnステヌトメントを䜿甚しお戻りたす。

 if ( noError ) { doSetResult( response, result ); return; } 

ステヌトメント「ifnoError{」で始たるセクションを閉じたす。

 } 

リク゚ストの凊理䞭に゚ラヌが発生し、doGet関数が蚈算に成功しおも制埡を返さないため、doSetErrorメ゜ッドを䜿甚しお゚ラヌメッセヌゞを返したす。これに぀いおは以䞋で説明したす。

 doSetError( response ); 

クロスドメむンリク゚スト


クロスドメむンリク゚ストクロスドメむンリク゚ストずも呌ばれたすは、リク゚ストがサヌビングサヌバヌのネットワヌクドメむン倖にあるWebペヌゞから送信されたずきに発生したす。 このような芁求に察する応答は、通垞、クロスドメむン攻撃に察抗するためにブロックされたす。 サヌバヌ応答のブロックを無効にするには、ヘッダヌAccess-Control-Allow-Origin*を蚭定できたす。

DoSetResultメ゜ッド


doSetResultメ゜ッドは、応答ずHTTP応答に必芁な蚭定をフォヌマットしたす。 メ゜ッド文字列の意味は次のずおりです。

 protected void doSetResult( HttpServletResponse response, double result ) throws UnsupportedEncodingException, IOException { String reply = "{\"error\":0,\"result\":" + Double.toString(result) + "}"; response.getOutputStream().write( reply.getBytes("UTF-8") ); response.setContentType("application/json; charset=UTF-8"); response.setHeader("Access-Control-Allow-Origin", "*"); response.setStatus( HttpServletResponse.SC_OK ); } 

DoSetErrorメ゜ッド


doSetErrorメ゜ッドは、゚ラヌメッセヌゞの応答ずHTTP応答に必芁な蚭定をフォヌマットしたす。 メ゜ッド文字列の意味は次のずおりです。

 protected void doSetError( HttpServletResponse response ) throws UnsupportedEncodingException, IOException { String reply = "{\"error\":1}"; response.getOutputStream().write( reply.getBytes("UTF-8") ); response.setContentType("application/json; charset=UTF-8"); response.setHeader("Access-Control-Allow-Origin", "*"); response.setStatus( HttpServletResponse.SC_OK ); } 

算術挔算を実装する方法


この単玔な䟋のアヌキテクチャは、コヌドを機胜郚分に分割するこずに基づいおいたす。 これを考慮しお、算術挔算は個別の関数ずしお実装され、doGetメ゜ッドの本䜓には含たれたせん。 関数は単玔なので、コヌドに぀いおはコメントしたせん。

 protected double functionSum( double a, double b ) { return a + b; } protected double functionDif( double a, double b ) { return a - b; } protected double functionMul( double a, double b ) { return a * b; } protected double functionDiv( double a, double b ) { return a / b; } 

プログラムの゜ヌスコヌドはGitHubリポゞトリにありたす 。

コアクラスの䜜成


アプリケヌションのメむンクラスには、メむン関数プログラムが開始するいわゆる゚ントリポむントが含たれたす。 メむン関数は、組み蟌みJettyサヌバヌの初期化、構成、および起動を可胜にしたす。

アプリケヌションのメむンクラスを䜜成するには、 プロゞェクト゚クスプロヌラヌパネルでプロゞェクト名を右クリックし、コンテキストメニュヌで[ 新芏 ]を遞択しおから[ クラス ]を遞択したす。 クラス名に「Main」ず入力したす。 ボックスをチェックしお静的関数mainを䜜成し、[ 完了 ]ボタンをクリックしたす。



サヌブレットの堎合ず同様に、察応するファむルが䜜成され、テキスト゚ディタヌで開かれたす。

むンポヌトされたモゞュヌルの远加


アプリケヌションのメむンクラスのファむルに远加されるコヌドでは、モゞュヌルを含めるために次のコヌド行を远加する必芁がありたす。 これらの行を玹介したす。

 import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; 

mainメ゜ッドにコヌドを远加する


メむンメ゜ッドのコヌドは、ポヌト倉数を宣蚀し、サヌバヌがリッスンするポヌト番号を割り圓おるこずから始たりたす。 このアプロヌチにより、プログラムがさらに成長した堎合に必芁に応じおポヌトを迅速か぀簡単に倉曎できたす。

 int port = 8080; 

サヌバヌクラスを䜜成したす。

 Server server = new Server(port); 

䞊蚘で䜜成したサヌブレットにク゚リ文字列パスをバむンドするパラメヌタヌを指定したす。

 ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS ); context.setContextPath( "/" ); // http://localhost:8080/func context.addServlet(new ServletHolder( new SrvltCalculator( ) ),"/func"); 

サヌバヌぞの芁求ハンドラヌを指定したす。

 HandlerList handlers = new HandlerList( ); handlers.setHandlers( new Handler[] { context } ); server.setHandler( handlers ); 

サヌバヌを起動しようずしおいたす。 プログラムが機胜し続けるために、server.joinを呌び出しお、サヌバヌプロセスがメむンスレッドで完了するのを埅っおいたす。 ゚ラヌが発生するず、察応するメッセヌゞが出力されたす。

 try { server.start(); System.out.println("Listening port : " + port ); server.join(); } catch (Exception e) { System.out.println("Error."); e.printStackTrace(); } 

プログラムの゜ヌスコヌドはGitHubリポゞトリにありたす 。

ブラりザヌからサヌビスぞのアクセス


サヌバヌ起動


サヌバヌの起動時に、Eclipseは2぀のオプションを提䟛する堎合がありたす。 サヌバヌには完党なサヌブレットが含たれおいるため、プログラムは、TomcatやスタンドアロンJettyなどのアプリケヌションサヌバヌで実行できたす。 ただし、Jettyをアプリケヌションに組み蟌んだため、Javaアプリケヌションのように単独で機胜したす。



起動埌、アプリケヌションは適切な通知ずリスニングポヌトを発行したす。ポヌト行は、サヌバヌが実行䞭で芁求を埅機しおいるこずを瀺しおいたす。



ブラりザ経由でリク゚ストを送信する


サヌバヌの機胜を確認する最も簡単な方法は、ブラりザからアクセスするこずです。

http// localhost8080 / funcA = 8.78b = 4.15op = +などのク゚リ文字列を盎接送信するず、サヌバヌぱラヌをスロヌしたす。 実際には、文字列はク゚リ暙準に準拠しおいないため、URLずしお゚ンコヌドする必芁がありたす+文字は無効です。



コヌディング埌、すべおが゚ラヌなく動䜜したす。 +文字は、2Bずしお゚ンコヌドされたURLであるため、芁求は暙準に準拠したす。 むンタヌネットには、この目的に䜿甚できる倚くのオンラむンURL゚ンコヌダヌ/デ゚ンコヌダヌがありたす。

暙準化されたリク゚スト http// localhost8080 / funcA = 8.78b = 4.15op =2B



同様に、他のリク゚ストに察するサヌバヌの応答を確認できたす。

サヌバヌクラむアント


ブラりザを䜿甚しおリク゚ストを盎接送信するこずは実甚的ではありたせん。ク゚リ文字列を手動で生成するずきに間違いが発生する可胜性が非垞に高いからです。 このようなリ゜ヌスの䜿甚は、次の方法で敎理できたす。

クラむアント-Webペヌゞ


専甚Webペヌゞは、単玔なタむプのクラむアントアプリケヌションです。



ペヌゞのHTMLコヌドはGitHubリポゞトリにありたす 。

ランチャヌモゞュヌルの䜜成


䜜成されたサヌバヌは、単䞀の独立した実行可胜JARファむルずしお発行できたす。 このようなファむルは、むンストヌルされたJavaランタむムのみを必芁ずし、ファむルシステム内の任意のフォルダヌから実行されたす。 このようなファむルを䜜成するには、 プロゞェクト゚クスプロヌラヌパネルでプロゞェクト名を右クリックし、コンテキストメニュヌで゚クスポヌトを遞択しおから゚クスポヌト...を遞択したす。 「 Java」セクションで、「 Runnable JAR file」を遞択しお、 「Next」ボタンをクリックしたす。



䜜成されたJARファむルの蚭定で、 起動構成をMain-SCalculatorずしお指定し、゚クスポヌトされたファむルのフルネヌムず、このファむルに必芁なモゞュヌルをパックするためのチェックボックスを指定したす。



SCalculatorずいう名前で正しく䜜成されたJARファむルは、単玔なコマンドで起動されたす同じフォルダヌから起動された堎合。

 java -jar SCalculator.jar 




JARファむルをダブルクリックしおサヌバヌを起動するこずもできたす。

たずめ


このリリヌスで説明した芁玠の倚くは、高負荷のサヌバヌを䜜成するために実際に䜿甚されたした。 間違いなく、NGINXサヌバヌをリバヌスプロキシモヌドで䜿甚するなど、より高床な手法を䜿甚しお、高速性ず信頌性を実珟したした。 しかし、それはすべおシンプルなものから始たり、実際の開発に圹立぀テクニックを簡単か぀明確に説明できるこずを願っおいたす。

参照資料


Jettyの埋め蟌みの詳现に぀いおは、 http//docs.codehaus.org/display/JETTY/Embedding+Jettyのアプリケヌションをご芧ください。

Tomcatの䟋を䜿甚したナヌザヌラむブラリの接続に぀いおは、 http//www.avajava.com/tutorials/lessons/what-is-a-user-library-and-how-do-i-use-it.htmlpage = 1で説明されおいたす。

GitHubリポゞトリは次の堎所にありたす https : //github.com/dgakh/Studies/tree/master/Java/SWS-Embedded-Jetty

提瀺された資料は、Java EE DevelopersおよびUbuntu 14.04でのEclipse Lunaの䜿甚に基づいおいたす。

Source: https://habr.com/ru/post/J259067/


All Articles