Fuga Framework-Java用の小さなWebフレームワーク

この記事では、Fuga Frameworkと控えめに呼んでいる私のフレームワークについてお話したいと思います。











叙情的な紹介



私が2年目にいたとき、理論物理学と実験物理学の1つの研究室用のWebアプリケーションの開発に招待されました。 アプリケーション自体は非常にシンプルでしたが、いくつかの珍しい機能がありました。 最初のステップは、このアプリケーションの開発を開始する言語とテクノロジを選択することでした。 ためらうことなく、私はフレームワークを使用せずにPHPですべてを行うことにしました。 もちろん、私は知っていたすべてのオプションを検討しましたが、アプリケーションは単純に見えたので、あまり気にしませんでした。 一週間後、私はすでにアプリケーションの予備バージョンを完成させました。



結果はうまくいきました。 しかし、しばらくして、私は不満を感じ、いつでもすべてが壊れるのではないかと心配しました。 無駄ではありません。 アプリケーションがホストされたとき、多くのバグが蓄積されました。 これらのとんでもない間違いを修正し始めて、私はまだ何らかのフレームワークを使用しなければならないことに気付きました。



その瞬間、「Javaでのプログラミング」コースを開始しました。このコースでは、試験を受けるために、学期の終わりにこの言語で作成されたプロジェクトを提出する必要がありました。 そして、Javaマイクロフレームワークを作成するというアイデアを得ました。 私はまだ実験室用の不器用なアプリケーションをやり直す必要があったので、このアプリケーション専用のマイクロフレームワークを学期全体で費やしました。 このフレームワークを作成するとき、私は人気のあるPlayフレームワークに触発されました。 その結果、研究室用の実用的なWebアプリケーションを手に入れました。これはJavaで書かれているだけでなく、はるかに安定しており、簡単に拡張できることがわかりました。 私の「プログラマー」の幸福には限界がありませんでした。 フレームワークの記述に触発されて、私はそれをアプリケーション自体から分離し、リファクタリングを行い、あらゆる種類の可能性で拡張し始めました。 私はこのフレームワークを1つのトレーニングと2つの他の個人プロジェクトで成功裏に使用し、経験豊富な開発者からも良いレビューを受けました。



開始する



Fuga Frameworkは、依存関係のNettyとlog4jのみを必要とする組み込みWebフレームワークです。 これにより、フレームワークを使用して従来のWebアプリケーションを作成できるだけでなく、他のアプリケーションに埋め込み、Webインターフェイスを簡単に作成できます。 現在、Fuga FrameworkにはHTTPサーバー、ルーター、テンプレートエンジンが含まれています。



Fuga Frameworkを使用するアプリケーションには、少なくとも3つのファイルが必要です。



メインクラスでは、アプリケーションを構成し、Webサーバーを起動します。



package com.example; import com.showvars.fugaframework.FugaApp; public class HelloWorldApp extends FugaApp { @Override public void prepare() { getRouter().loadFromResources("/routes/helloworld.routesmap"); } public static void main(String[] args) throws Exception { new HelloWorldApp().start(); } }
      
      





ここでは、特別なファイルを使用してルーターを構成するだけです。 以下に例を示します。



 use com.example.controllers GET $/ HelloWorldController.index()
      
      





最初の行では、パッケージのインポートを行いました。これにより、将来、パッケージ名を含む完全なパスをコントローラークラスに書き込むことができなくなります。 次の行では、正規表現/



一致するGET



HelloWorldController



クラスのindex()



メソッドに転送する必要があることをルーターに伝えます。 Playフレームワークに出会った場合、このルーティングファイルがPlayフレームワークの類似ファイルと類似していることに気付くかもしれません。 しかし実際には、Fuga Frameworkでは、追加の設計を使用してルーターをより柔軟に構成できます。これについては後で説明します。



そのため、ルーティングプランファイルで、 HelloWorldController



クラスにあるindex()



メソッドにリクエストを送信しました。 作成しましょう:



 package com.example.controllers; import com.showvars.fugaframework.foundation.* public class HelloWorldController extends Controller { public static Response index(Context ctx) throws Exception { return ok(" !"); } }
      
      





ルーターが呼び出すメソッドはすべて静的であり、 Context



型のオブジェクトを最初の引数として必ず受け入れる必要があります。 このオブジェクトは、Cookieやセッションを含む現在のリクエストへのリンク、およびサーバーインスタンスへのリンクを保存します。 Controller



クラスから、 ok()



proceed()



notFound()



redirect()



などの便利な静的メソッドのみを継承します。



できた! これで、アプリケーションを起動してブラウザーを開くことができます: http:// localhost:8080 /



カスタマイズ



Webサーバー、テンプレートエンジン、その他のすべてのConfiguration



は、 Configuration



オブジェクトのset()



メソッドを使用して行われます。 このオブジェクトは、 prepare()



メソッドのgetterを使用するか、コントローラーのContext



オブジェクトから取得できます。



ルーター



必要に応じて、ルーティング計画をより複雑に説明できます。 現時点では、次の設計を使用する機能が実装されています。



正規表現では、キャプチャグループを使用して、その値をコントローラーに渡すことができます。



 GET $/(.*) com.example.ExampleController.index(1)
      
      





定数をコントローラーに入力し、値のタイプを示すことができます。 この場合、それらは自動的にリストされます:



 GET $/(\d+) com.example.ExampleController.index(1:int, "3.14":double, "some string")
      
      





最初の2つのルートパラメータはオプションであり、任意の順序で記述できます。



 com.example.ExampleController.index() GET com.example.ExampleController.index() GET $/hello com.example.ExampleController.index() $/hello GET com.example.ExampleController.index()
      
      





1つのルートは、複数のコントローラーに順番に要求を送信できます。



 GET $/(\d+) { HelloWorldController.check(1:int) HelloWorldController.index() }
      
      





コントローラがproceed()



またはnullを返す場合、ルータはリスト内の次のコントローラを実行しようとします。



ネストされたルート:



 $/page/(\d*) { GET $/page/(\d+) HelloWorldController.get(1:int) POST $/page/(\d+) HelloWorldController.post(1:int) GET { HelloWorldController.check(0) HelloWorldController.index() } }
      
      





事前定義されたメソッドを使用して、ユーザーに静的にすばやく返すことができます。



 GET $/(.*) asset(1:String) GET $/ view("index.html")
      
      





テンプレートエンジン



Fugaフレームワークでは、テンプレートエンジンはMozilla Rhino JavaScriptエンジンに基づいており、これはデフォルトでJRE 7以降に統合されています。



出力では、タグ{# <> #}



を使用し、JavaScript式が挿入されます。 また、単純なコードを挿入するには、タグ{% <> %}



同様に使用されます。 フォームの構成を使用して他のテンプレートを展開することもできます。



 @extend base.html {% block content %} <h2> !</h2> {% endblock %}
      
      





テンプレートをユーザーに表示するには、 Controller



クラスのview()



メソッドを使用する必要があります。



 return ok(view("index.html"));
      
      





コントローラーではなく、ルーティングプラン書き込みview()



直接:



 GET $/ view("index.html")
      
      





デフォルトでは、テンプレートエンジンは、最初に呼び出されたときにテンプレートをコンパイルしてキャッシュします。 ただし、 fuga.templates.alwaysrecompile



パラメーターを変更することにより、テンプレートが毎回再コンパイルされるようにすることfuga.templates.alwaysrecompile



できfuga.templates.alwaysrecompile



。 これにより、サーバーを再起動せずにテンプレートをすばやく編集できます。



テンプレートを作成するとき、JavaScript言語だけでなく自由に使用できます。 Mozilla Rhinoエンジンを使用すると、すべてのJavaクラスにアクセスできるため、 Context



およびTemplateApi



クラスのオブジェクトだけでなく、標準ライブラリ全体も取得できます。 1つ目はコントローラーへの入力と同じもので、2つ目はasset()



escape()



などの便利な機能のセットを持つクラスです。 例:



 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html" /> <link href="{# api.asset('css/common.css') #}" rel="stylesheet" type="text/css" /> </head> {% var session = context.getSession(); %} <body> <div id="content"> <h3> , {# session.getString('user') #}</h3> {% block content %}{% endblock %} </div> <script src="{# api.asset('js/common.js') #}"></script> {% block js %}{% endblock %} </body> </html>
      
      





おわりに



フレームワークを作成するとき、私は標準や確立された原則に導かれませんでした。 さらに、このフレームワークは非常に粗雑です。 したがって、私はコメントや提案を聞いて考慮に入れる準備ができています;)



GitHub: https : //github.com/IntCode/Fuga-Framework



All Articles