Blade –完全なガイドブック

  • Java

  • link:/category/programming/ [プログラミング]

1. 概要

https://lets-blade.com/[Blade]は、小さなJava 8+ MVCフレームワークであり、明確な目標を念頭に置いてゼロから構築されています。
Nodeのhttps://expressjs.com/[Express]、Pythonのhttp://flask.pocoo.org/[Flask]、Golangのhttps://github.com/go-macaron/macaronなど、多くの異なるフレームワークが設計に影響を与えました。 [マカロン] / https://github.com/go-martini/martini[Martini]。
また、Bladeは、野心的に大きなプロジェクトhttps://github.com/lets-blade[Let's Blade]の一部です。 Captcha生成からJSON変換、テンプレート化から単純なデータベース接続まで、他の小さなライブラリの異種コレクションが含まれます。
ただし、このチュートリアルでは、MVCのみに焦点を当てます。

2. 入門

まず、空のMavenプロジェクトを作成して、_pomにhttps://search.maven.org/search?q=g:com.bladejava%20AND%20a:blade-mvc [最新のBlade MVC依存関係]を追加します。 xml_:
<dependency>
    <groupId>com.bladejava</groupId>
    <artifactId>blade-mvc</artifactId>
    <version>2.0.14.RELEASE</version>
</dependency>

* 2.1。 ブレードアプリケーションのバンドル*

アプリはJARとして作成されるため、WARのように_ / lib_フォルダーはありません。 その結果、_blade-mvc_ JARと必要な他のJARをアプリに提供する方法の問題につながります。
これを行うさまざまな方法は、それぞれ長所と短所があり、https://www.baeldung.com/executable-jar-with-maven [Mavenで実行可能JARを作成する方法]チュートリアルで説明されています。
簡単にするために、* _ pom.xml_にインポートされたJARを展開し、その後すべてのクラスを1つのuber-JARにバンドルする_Maven Assembly Plugin_テクニック*を使用します。

* 2.2。 ブレードアプリケーションの実行*

*ブレードはlink:/netty[Netty]*に基づいています。これは、驚くべき非同期イベント駆動型ネットワークアプリケーションフレームワークです。 したがって、ブレードベースのアプリケーションを実行するために、外部のアプリケーションサーバーもサーブレットコンテナも必要ありません。 JREで十分です。
java -jar target/sample-blade-app.jar
その後、アプリケーションはhttp:// localhost:9000 _ URLでアクセス可能になります。

3. アーキテクチャについて

Bladeのアーキテクチャは非常に簡単です。
link:/uploads/architecture-100x141.png%20100w []
常に同じライフサイクルに従います。
  1. Nettyはリクエストを受け取ります

  2. ミドルウェアが実行されます(オプション)

  3. WebHooksが実行されます(オプション)

  4. ルーティングが実行されます

  5. 応答がクライアントに送信されます

  6. 掃除

    次のセクションでは、上記の機能について説明します。

4. ルーティング

つまり、MVCのルーティングは、URLとコントローラー間のバインディングを作成するために使用されるメカニズムです。
Bladeには、基本ルートと注釈付きルートの2種類のルートがあります。

* 4.1。 基本ルート*

基本ルートは、マイクロサービスや最小限のWebアプリケーションなど、非常に小さなソフトウェアを対象としています。
Blade.of()
  .get("/basic-routes-example", ctx -> ctx.text("GET called"))
  .post("/basic-routes-example", ctx -> ctx.text("POST called"))
  .put("/basic-routes-example", ctx -> ctx.text("PUT called"))
  .delete("/basic-routes-example", ctx -> ctx.text("DELETE called"))
  .start(App.class, args);
ルートの登録に使用されるメソッドの名前は、リクエストの転送に使用されるHTTP動詞に対応しています。 それと同じくらい簡単です。
この場合、テキストを返しますが、このチュートリアルで後述するように、ページをレンダリングすることもできます。

* 4.2。 注釈付きルート*

確かに、より現実的なユースケースでは、アノテーションを使用して必要なすべてのルートを定義できます。 そのために別個のクラスを使用する必要があります。
まず、_ @ Path_アノテーションを使用してコントローラーを作成する必要があります。これは、起動時にBladeによってスキャンされます。
次に、インターセプトするHTTPメソッドに関連するルートアノテーションを使用する必要があります。
@Path
public class RouteExampleController {

    @GetRoute("/routes-example")
    public String get(){
        return "get.html";
    }

    @PostRoute("/routes-example")
    public String post(){
        return "post.html";
    }

    @PutRoute("/routes-example")
    public String put(){
        return "put.html";
    }

    @DeleteRoute("/routes-example")
    public String delete(){
        return "delete.html";
    }
}
単純な_ @ Route_アノテーションを使用して、HTTPメソッドをパラメーターとして指定することもできます。
@Route(value="/another-route-example", method=HttpMethod.GET)
public String anotherGet(){
    return "get.html" ;
}
一方、*メソッドパラメータを指定しない場合、動詞に関係なく、ルートはそのURLへのすべてのHTTP呼び出しをインターセプトします*。

* 4.3。 パラメータ注入*

ルートにパラメーターを渡す方法はいくつかあります。 https://lets-blade.com/docs/route.html#%E5%8F%82%E6%95%B0%E6%B3%A8%E5%85%A5 [ドキュメントから]。
  • フォームパラメータ:

@GetRoute("/home")
public void formParam(@Param String name){
    System.out.println("name: " + name);
}
  • 安らかなパラメーター:

@GetRoute("/users/:uid")
public void restfulParam(@PathParam Integer uid){
    System.out.println("uid: " + uid);
}
  • ファイルアップロードパラメータ:

@PostRoute("/upload")
public void fileParam(@MultipartParam FileItem fileItem){
    byte[] file = fileItem.getData();
}
  • ヘッダーパラメーター:

@GetRoute("/header")
public void headerParam(@HeaderParam String referer){
    System.out.println("Referer: " + referer);
}
  • Cookieパラメーター:

@GetRoute("/cookie")
public void cookieParam(@CookieParam String myCookie){
    System.out.println("myCookie: " + myCookie);
}
  • 本体パラメーター:

@PostRoute("/bodyParam")
public void bodyParam(@BodyParam User user){
    System.out.println("user: " + user.toString());
}
  • 属性をルートに送信することによって呼び出される値オブジェクトパラメーター:

@PostRoute("/voParam")
public void voParam(@Param User user){
    System.out.println("user: " + user.toString());
}
<form method="post">
    <input type="text" name="age"/>
    <input type="text" name="name"/>
</form>

5. 静的リソース

Bladeは、必要に応じて、_ / resources / static_フォルダー内に配置するだけで、静的リソースを提供することもできます。
たとえば、_src / main / resources / static / app.css_は_http:// localhost:9000 / static / app.css_で利用できます。

* 5.1。 パスのカスタマイズ*

プログラムで1つ以上の静的パスを追加することにより、この動作を調整できます。
blade.addStatics("/custom-static");
ファイル_src / main / resources / application.properties_を編集することにより、構成を通じて同じ結果が得られます。
mvc.statics=/custom-static

* 5.2。 リソースリストの有効化*

静的フォルダのコンテンツのリストを許可することができます。セキュリティ上の理由でデフォルトでオフになっている機能です。
blade.showFileList(true);
または構成:
mvc.statics.show-list=true
これで、:// http:// localhost:9000 / custom-static / _を開いて、フォルダーの内容を表示できます。

* 5.3。 WebJars *を使用する

link:/maven-webjars[Introduction to WebJars]チュートリアルで見られるように、JARとしてパッケージ化された静的リソースも実行可能なオプションです。
Bladeは、_ / webjars / _パスの下でそれらを自動的に公開します。
たとえば、_pom.xml_のhttps://search.maven.org/search?q=g:org.webjars%20AND%20a:bootstrap[Bootstrap]をインポートしましょう。
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>4.2.1</version>
</dependency>
その結果、_http:// localhost:9000 / webjars / bootstrap / 4.2.1 / css / bootstrap.css_で利用可能になります

6. HTTPリクエスト

  • Bladeはサーブレット仕様*に基づいていないため、そのインターフェース_http://lets-blade.com/apidocs/index.html?com / blade / mvc / http / Request.html [Request] _およびそのクラスのようなオブジェクト_http://lets-blade.com/apidocs/index.html?com / blade / mvc / http / HttpRequest.html [HttpRequest] _は、以前とは少し異なります。

* 6.1。 フォームパラメータ*

フォームパラメーターを読み取るとき、Bladeはクエリメソッドの結果でJava Optionalを最大限に活用します(以下のすべてのメソッドは_Optional_ objectを返します)。
  • query(String name)

  • queryInt(文字列名)

  • queryLong(文字列名)

  • queryDouble(String name)

    フォールバック値を使用することもできます:
  • String query(String name、String defaultValue)

  • int queryInt(String name、int defaultValue)

  • long queryLong(String name、long defaultValue)

  • double queryDouble(String name、double defaultValue)

    automappedプロパティを介してフォームパラメーターを読み取ることができます。
@PostRoute("/save")
public void formParams(@Param String username){
    // ...
}
または_Request_オブジェクトから:
@PostRoute("/save")
public void formParams(Request request){
    String username = request.query("username", "Baeldung");
}

* 6.2。 JSONデータ*

次に、JSONオブジェクトをPOJOにマッピングする方法を見てみましょう。
curl -X POST http://localhost:9000/users -H 'Content-Type: application/json' \
  -d '{"name":"Baeldung","site":"baeldung.com"}'
POJO(読みやすくするためにlink:/intro-to-project-lombok[Lombok]で注釈を付けています):
public class User {
    @Getter @Setter private String name;
    @Getter @Setter private String site;
}
繰り返しますが、値は挿入されたプロパティとして使用できます。
@PostRoute("/users")
public void bodyParams(@BodyParam User user){
    // ...
}
そして_Request_から:
@PostRoute("/users")
public void bodyParams(Request request) {
    String bodyString = request.bodyToString();
}

* 6.3。 RESTfulパラメーター*

_localhost:9000 / user / 42_のようなきれいなURLのRESTFulパラメーターも一流の市民です:
@GetRoute("/user/:id")
public void user(@PathParam Integer id){
    // ...
}
いつものように、必要なときに_Request_オブジェクトに依存できます。
@GetRoute("/user")
public void user(Request request){
    Integer id = request.pathInt("id");
}
明らかに、_Long_型と_String_型にも同じメソッドを使用できます。

* 6.4。 データバインディング*

BladeはJSONとFormの両方のバインディングパラメータをサポートし、それらをモデルオブジェクトに自動的に付加します。
@PostRoute("/users")
public void bodyParams(User user){}

* 6.5。 リクエストとセッションの属性+

*
a _Request_およびa _Session_でオブジェクトを読み書きするためのAPIは非常に明確です。
キーと値を表す2つのパラメーターを持つメソッドは、異なるコンテキストに値を格納するために使用できるミューテーターです。
Session session = request.session();
request.attribute("request-val", "Some Request value");
session.attribute("session-val", 1337);
一方、キーパラメータのみを受け入れる同じメソッドはアクセサです。
String requestVal = request.attribute("request-val");
String sessionVal = session.attribute("session-val"); //It's an Integer
興味深い機能はhttps://github.com/lets-blade/blade/blob/master/src/main/java/com/blade/mvc/http/Request.java#L500 [それらの一般的な戻り値の型<T> T ]、結果をキャストする必要がなくなります。

* 6.6 ヘッダー*

それどころか、リクエストヘッダーはリクエストからのみ読み取ることができます。
String header1 = request.header("a-header");
String header2 = request.header("a-safe-header", "with a default value");
Map<String, String> allHeaders = request.headers();

* 6.7。 ユーティリティ*

次のユーティリティメソッドもすぐに使用できます。これらは非常に明確であるため、さらに説明する必要はありません。
  • boolean isIE()

  • boolean isAjax()

  • String contentType()

  • String userAgent()

* 6.8 クッキーの読み取り*

特に_Optional <Cookie> _を読むときに、_Request_オブジェクトがCookieの処理にどのように役立つかを見てみましょう。
Optional<Cookie> cookieRaw(String name);
Cookieが存在しない場合に適用するデフォルト値を指定することにより、a__String_として取得することもできます。
String cookie(String name, String defaultValue);
最後に、これはすべてのCookieを一度に読み取る方法です(_keys_はCookieの名前、_values_はCookieの値です)。
Map<String, String> cookies = request.cookies();

7. HTTPレスポンス

_Request_で行われたものと同様に、ルーティングメソッドのパラメーターとして宣言するだけで、_Response_オブジェクトへの参照を取得できます。
@GetRoute("/")
public void home(Response response) {}

* 7.1。 シンプルな出力*

200のHTTPコードと適切なContent-Typeとともに、便利な出力メソッドの1つを使用して、簡単な出力を簡単に呼び出し元に送信できます。
まず、プレーンテキストを送信できます。
response.text("Hello World!");
次に、HTMLを作成できます。
response.html("<h1>Hello World!</h1>");
第三に、同様にXMLを生成できます。
response.xml("<Msg>Hello World!</Msg>");
最後に、_String_を使用してJSONを出力できます。
response.json("{\"The Answer\":42}");
また、自動JSON変換を活用したPOJOからでも:
User user = new User("Baeldung", "baeldung.com");
response.json(user);

* 7.2。 ファイル出力*

サーバーからファイルをダウンロードするのは簡単ではありません。
response.download("the-file.txt", "/path/to/the/file.txt");
最初のパラメーターはダウンロードされるファイルの名前を設定し、2番目のパラメーター(ここでは_String_で構築された_File_オブジェクト)はサーバー上の実際のファイルへのパスを表します。

* 7.3。 テンプレートのレンダリング*

Bladeは、テンプレートエンジンを介してページをレンダリングすることもできます。
response.render("admin/users.html");
テンプレートのデフォルトディレクトリは_src / main / resources / templates / _であるため、以前のワンライナーは_src / main / resources / templates / admin / users.html_ファイルを探します。
これについては、後で「テンプレート」セクションで詳しく説明します。

* 7.4。 リダイレクト*

リダイレクトとは、2番目のGETに続くURLとともに302 HTTPコードをブラウザーに送信することを意味します。
別のルートまたは外部URLにリダイレクトすることもできます。
response.redirect("/target-route");

* 7.5 Cookieの作成*

この時点で、Bladeのシンプルさに慣れる必要があります。 このように、有効期限のないCookieを1行のコードで記述する方法を見てみましょう。
response.cookie("cookie-name", "Some value here");
実際、Cookieの削除も同様に簡単です。
response.removeCookie("cookie-name");

* 7.6。 その他の操作*

最後に、_Response_オブジェクトは、ヘッダーの作成、Content-Typeの設定、ステータスコードの設定などの操作を実行する他のいくつかのメソッドを提供します。
それらのいくつかを簡単に見てみましょう:
  • 応答ステータス(intステータス)

  • Map headers()

  • 応答notFound()

  • Map cookies()

  • Response contentType(String contentType)

  • void body(@NonNull byte [] data)

  • 応答ヘッダー(文字列名、文字列値)

*8. WebHooks *

WebHookはインターセプターであり、これを介して*ルーティングメソッドの実行前後にコードを実行できます*。
_WebHook_機能インターフェイスを実装し、_before()_メソッドをオーバーライドするだけで、WebHookを作成できます。
@FunctionalInterface
public interface WebHook {

    boolean before(RouteContext ctx);

    default boolean after(RouteContext ctx) {
        return true;
    }
}
ご覧のとおり、_after()_はデフォルトのメソッドであるため、必要な場合にのみオーバーライドします。

* 8.1。 すべてのリクエストをインターセプト*

_ @ Bean_アノテーションは、フレームワークにIoCコンテナーでクラスをスキャンするよう指示します。
その結果、アノテーションが付けられたWebHookはグローバルに機能し、すべてのURLへのリクエストをインターセプトします。
@Bean
public class BaeldungHook implements WebHook {

    @Override
    public boolean before(RouteContext ctx) {
        System.out.println("[BaeldungHook] called before Route method");
        return true;
    }
}

* 8.2。 URLへの絞り込み*

特定のURLをインターセプトして、これらのルートメソッドの周りでのみコードを実行することもできます。
Blade.of()
  .before("/user/*", ctx -> System.out.println("Before: " + ctx.uri()));
  .start(App.class, args);

* 8.3。 ミドルウェア*

ミドルウェアは優先順位付けされたWebHookであり、標準のWebHookの前に実行されます。
public class BaeldungMiddleware implements WebHook {

    @Override
    public boolean before(RouteContext context) {
        System.out.println("[BaeldungMiddleware] called before Route method and other WebHooks");
        return true;
    }
}
単に_ @ Bean_アノテーションなしで定義し、_use()_を介して宣言的に登録する必要があります。
Blade.of()
  .use(new BaeldungMiddleware())
  .start(App.class, args);
さらに、Bladeには次のセキュリティ関連の組み込みミドルウェアが付属しています。これらのミドルウェアの名前は一目瞭然です。

9. 構成

  • Bladeでは、すべてが慣習的にすぐに使用できるため、構成は完全にオプションです。*ただし、_src / main / resources / application.properties_ファイル内でデフォルト設定をカスタマイズし、新しい属性を導入できます。 。

* 9.1。 構成の読み取り*

設定が利用できない場合、デフォルト値を指定してもしなくても、さまざまな方法で設定を読み取ることができます。
  • 起動中:

Blade.of()
  .on(EventType.SERVER_STARTED, e -> {
      Optional<String> version = WebContext.blade().env("app.version");
  })
  .start(App.class, args);
  • ルート内:

@GetRoute("/some-route")
public void someRoute(){
    String authors = WebContext.blade().env("app.authors","Unknown authors");
}
  • カスタムローダーで、BladeLoader_インターフェースを実装することにより、
    _load()_メソッドをオーバーライドし、クラスに
    @ Bean_アノテーションを付けます:

@Bean
public class LoadConfig implements BladeLoader {

    @Override
    public void load(Blade blade) {
        Optional<String> version = WebContext.blade().env("app.version");
        String authors = WebContext.blade().env("app.authors","Unknown authors");
    }
}

* 9.2。 構成属性*

いくつかの設定はすでに構成されていますが、カスタマイズの準備ができており、タイプごとにグループ化され、https://lets-blade.com/docs/configuration.html#%E9%85%8D%E7%BD%AE%E6%B8がリストされています3列のテーブル(名前、説明、デフォルト値)の%85%E5%8D%95 [at this address]。 https://translate.google.com/translate?hl=ja&sl=zh-CN&tl=en&u=https%3A%2F%2Flets-blade.com%2Fdocs%2Fconfiguration.html%23%E9%85も参照できます。 %8D%E7%BD%AE%E6%B8%85%E5%8D%95&sandbox = 1 [翻訳されたページ]、翻訳が誤って設定の名前を大文字にすることに注意してください。 実際の設定は完全に小文字です。
プレフィックスで構成設定をグループ化すると、それらを一度にマップに読み込めるようになります。これは、多くの設定がある場合に便利です。
Environment environment = blade.environment();
Map<String, Object> map = environment.getPrefix("app");
String version = map.get("version").toString();
String authors = map.get("authors","Unknown authors").toString();

* 9.3。 複数の環境の処理*

アプリを別の環境にデプロイする場合、たとえばデータベース接続に関連する設定など、異なる設定を指定する必要がある場合があります。 Bladeは、_application.properties_ファイルを手動で置き換える代わりに、さまざまな環境用にアプリを構成する方法を提供します。 すべての開発設定で_application.properties_を維持し、*異なるフォルダーのみを含む_application-prod.properties_などの同じフォルダーに他のファイルを作成することができます*。
起動時に、使用する環境を指定できます。フレームワークは、_application-prod.properties_の最も具体的な設定と、デフォルトの_application.properties_ファイルの他のすべての設定を使用してファイルをマージします。
java -jar target/sample-blade-app.jar --app.env=prod

10. テンプレート化

Bladeでのテンプレート化はモジュール式の側面です。 これは非常に基本的なテンプレートエンジンを統合しますが、ビューをプロが使用する場合は、外部テンプレートエンジンに依存する必要があります。 次に、GitHubのhttps://github.com/lets-blade/blade-template-engines[blade-template-engines]リポジトリにある* FreeMarker *、* Jetbrickで利用可能なエンジンから*エンジンを選択できます。 *、* Pebble *、* Velocity *、またはラッパーを作成して別のテンプレートをインポートすることもできます。
Bladeの著者は、https://search.maven.org/search?q = g:com.github.subchen%20AND%20a:jetbrick-template [Jetbrick]、別のスマートな中国のプロジェクトを提案しています。

* 10.1 デフォルトエンジンの使用*

デフォルトのテンプレートは、異なるコンテキストからの変数を_ $ \ {} _表記を使用して解析することにより機能します。
<h1>Hello, ${name}!</h1>

* 10.2。 外部エンジンの接続*

別のテンプレートエンジンへの切り替えは簡単です! エンジンの(ブレードラッパー)の依存関係をインポートするだけです。
<dependency>
    <groupId>com.bladejava</groupId>
    <artifactId>blade-template-jetbrick</artifactId>
    <version>0.1.3</version>
</dependency>
この時点で、そのライブラリを使用するようにフレームワークに指示する単純な構成を作成するだけで十分です。
@Bean
public class TemplateConfig implements BladeLoader {

    @Override
    public void load(Blade blade) {
        blade.templateEngine(new JetbrickTemplateEngine());
    }
}
その結果、_src / main / resources / templates / _の下のすべてのファイルが新しいエンジンで解析されます。その構文はこのチュートリアルの範囲外です。

* 10.3。 新しいエンジンのラッピング*

新しいテンプレートエンジンをラップするには、_TemplateEngine_インターフェイスを実装し、_render()_メソッドをオーバーライドする単一のクラスを作成する必要があります。
void render (ModelAndView modelAndView, Writer writer) throws TemplateException;
この目的のために、https://github.com/lets-blade/blade-template-engines/blob/master/blade-template-jetbrick/src/main/java/com/blade/mvc/をご覧ください。 view / template / JetbrickTemplateEngine.java [実際のJetbrickラッパーのコード]を見て、その意味を理解してください。

11. ロギング

ブレードは、_slf4j-api_をロギングインターフェイスとして使用します。
また、https://github.com/lets-blade/blade-log [_blade-log_]と呼ばれる構成済みのロギング実装も含まれています。 したがって、何もインポートする必要はありません。 _Logger_を定義するだけで、そのまま機能します。
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

* 11.1。 統合ロガーのカスタマイズ*

デフォルト設定を変更する場合は、次のパラメーターをシステムプロパティとして調整する必要があります。
  • ログレベル(「トレース」、「デバッグ」、「情報」、「警告」、「エラー」のいずれか):

# Root Logger
com.blade.logger.rootLevel=info

# Package Custom Logging Level
com.blade.logger.somepackage=debug

# Class Custom Logging Level
com.blade.logger.com.baeldung.sample.SomeClass=trace
  • 表示される情報:

# Date and Time
com.blade.logger.showDate=false

# Date and Time Pattern
com.blade.logger.datePattern=yyyy-MM-dd HH:mm:ss:SSS Z

# Thread Name
com.blade.logger.showThread=true

# Logger Instance Name
com.blade.logger.showLogName=true

# Only the Last Part of FQCN
com.blade.logger.shortName=true
  • ロガー:

# Path
com.blade.logger.dir=./logs

# Name (it defaults to the current app.name)
com.blade.logger.name=sample

* 11.2。 統合ロガーの除外*

統合されたロガーがすでに構成されていると、小さなプロジェクトを開始するのに非常に便利ですが、他のライブラリが独自のロギング実装をインポートする場合、簡単に終了する可能性があります。 そして、その場合、競合を避けるために統合されたものを削除することができます:
<dependency>
    <groupId>com.bladejava</groupId>
    <artifactId>blade-mvc</artifactId>
    <version>${blade.version}</version>
    <exclusions>
        <exclusion>
            <groupId>com.bladejava</groupId>
            <artifactId>blade-log</artifactId>
        </exclusion>
    </exclusions>
</dependency>

12. カスタマイズ

* 12.1。 カスタム例外処理*

例外ハンドラーもデフォルトでフレームワークに組み込まれています。 コンソールに例外を出力し、_app.devMode_が_true_の場合、スタックトレースもWebページに表示されます。
ただし、_DefaultExceptionHandler_クラスを拡張する_ @ Bean_を定義することにより、特定の方法で例外を処理できます。
@Bean
public class GlobalExceptionHandler extends DefaultExceptionHandler {

    @Override
    public void handle(Exception e) {
        if (e instanceof BaeldungException) {
            BaeldungException baeldungException = (BaeldungException) e;
            String msg = baeldungException.getMessage();
            WebContext.response().json(RestResponse.fail(msg));
        } else {
            super.handle(e);
        }
    }
}

* 12.2。 カスタムエラーページ*

同様に、エラー_404 – Not Found_および_500 – Internal Server Error_は、スキニーのデフォルトページで処理されます。
次の設定で_application.properties_ファイルで宣言することにより、フレームワークに独自のページを使用させることができます。
mvc.view.404=my-404.html
mvc.view.500=my-500.html
確かに、これらのHTMLページは_src / main / resources / templates_フォルダーの下に配置する必要があります。
500の内部では、特別な変数を介して例外_message_と_stackTrace_をさらに取得できます。
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>500 Internal Server Error</title>
    </head>
    <body>
        <h1> Custom Error 500 Page </h1>
        <p> The following error occurred: "<strong>${message}</strong>"</p>
        <pre> ${stackTrace} </pre>
    </body>
</html>

13. スケジュールされたタスク

フレームワークのもう1つの興味深い機能は、メソッドの実行をスケジュールできることです。
_ @ Schedule_アノテーションで_ @ Bean_クラスのメソッドに注釈を付けることで可能です。
@Bean
public class ScheduleExample {

    @Schedule(name = "baeldungTask", cron = "0 */1 * * * ?")
    public void runScheduledTask() {
        System.out.println("This is a scheduled Task running once per minute.");
    }
}
実際、従来のcron式を使用して、_DateTime_座標を指定します。 これらの詳細については、https://www.baeldung.com/cron-expressions [Cron Expressionsガイド]を参照してください。
後で、http://lets-blade.com/apidocs/com/blade/task/TaskManager.html [_TaskManager_]クラスの静的メソッドを利用して、スケジュールされたタスクで操作を実行する場合があります。
  • スケジュールされたすべてのタスクを取得します。

List<Task> allScheduledTasks = TaskManager.getTasks();
  • 名前でタスクを取得します。

Task myTask = TaskManager.getTask("baeldungTask");
  • 名前でタスクを停止します。

boolean closed = TaskManager.stopTask("baeldungTask");

14. イベント

セクション9.1で既に見たように、カスタムコードを実行する前に、指定されたイベントをリッスンすることができます。
Bladeは、すぐに使用可能な次のイベントを提供します。
public enum EventType {
    SERVER_STARTING,
    SERVER_STARTED,
    SERVER_STOPPING,
    SERVER_STOPPED,
    SESSION_CREATED,
    SESSION_DESTROY,
    SOURCE_CHANGED,
    ENVIRONMENT_CHANGED
}
最初の6つは簡単に推測できますが、最後の2つにはいくつかのヒントが必要です。 代わりに、_SOURCE_CHANGED_はまだ実装されておらず、将来の使用のためにのみ存在します。
セッションが作成されるたびにセッションに値を設定する方法を見てみましょう。
Blade.of()
  .on(EventType.SESSION_CREATED, e -> {
      Session session = (Session) e.attribute("session");
      session.attribute("name", "Baeldung");
  })
  .start(App.class, args);

15. セッション実装

セッションについて言えば、そのデフォルト実装はセッション値をメモリに保存します。
したがって、別の実装に切り替えて、キャッシュ、永続性などを提供することもできます。 たとえば、Redisを取り上げます。 https:// lets- blade.com/docs/session-ext.html[_HttpSession_のドキュメント]。
次に、それを使用したいことをフレームワークに知らせるだけです。 カスタムテンプレートエンジンで行ったのと同じ方法でこれを行うことができますが、唯一の違いは_sessionType()_メソッドを呼び出すことです。
@Bean
public class SessionConfig implements BladeLoader {

    @Override
    public void load(Blade blade) {
        blade.sessionType(new RedisSession());
    }
}

16. コマンドライン引数

コマンドラインからBladeを実行する場合、その動作を変更するために指定できる3つの設定があります。
まず、デフォルトでローカル_0.0.0.0_ループバックであるIPアドレスを変更できます。
java -jar target/sample-blade-app.jar --server.address=192.168.1.100
次に、ポートを変更することもできます。デフォルトでは_9000_です。
java -jar target/sample-blade-app.jar --server.port=8080
最後に、セクション9.3で見られるように、環境を変更して、異なる_application-XXX.properties_ファイルがデフォルトの_application.properties_を介して読み取られるようにすることができます。
java -jar target/sample-blade-app.jar --app.env=prod

17. IDEで実行中

最新のJava IDEは、Mavenプラグインを必要とせずにBladeプロジェクトを再生できます。 IDEでBladeを実行することは、フレームワークの機能を明示するために明示的に記述されたhttps://github.com/lets-blade/blade-demos[Blade Demos]を実行する場合に特に役立ちます。 これらはすべて親pomを継承するため、スタンドアロンアプリとして実行するように手動で調整するのではなく、IDEに作業を任せるのが簡単です。

* 17.1。 Eclipse *

Eclipseでは、プロジェクトを右クリックして_Javaアプリケーションとして実行_を起動し、_App_クラスを選択して、_OK_を押すだけで十分です。
ただし、Eclipseのコンソールでは、ANSIカラーが正しく表示されず、代わりにコードが流出します。
link:/uploads/Screenshot-from-2019-01-08-23-43-10-100x57.png%20100w []
幸いなことに、https://marketplace.eclipse.org/content/ansi-escape-console [コンソールのANSIエスケープ]拡張機能をインストールすると、問題が永久に修正されます。
link:/uploads/Screenshot-from-2019-01-08-23-44-25-100x57.png%20100w []

* 17.2。 IntelliJ IDEA *

IntelliJ IDEAはANSIカラーをそのまま使用できます。 したがって、プロジェクトを作成し、_App_ファイルを右クリックして、_Run 'App.main()' _(_Ctrl + Shift + F10_を押すのと同じ)を起動するだけで十分です。
link:/uploads/Screenshot-from-2019-01-12-00-44-01-100x57.png%20100w []

* 17.3。 Visual Studioコード*

https://code.visualstudio.com/docs/java/extensions[Java Extension Pack]を事前にインストールすることにより、一般的な非Java中心のIDEであるVSCodeを使用することもできます。
_Ctrl + F5_を押すと、プロジェクトが実行されます。
link:/uploads/Screenshot-from-2019-01-12-00-59-43-100x57.png%20100w []

18. 結論

Bladeを使用して小さなMVCアプリケーションを作成する方法を見てきました。
http://lets-blade.com/docs/ [ドキュメント全体]は、中国語のみで利用可能です。 https://lets-blade.com/ [中国の起源]のおかげで、主に中国で広く普及しているにもかかわらず、https://github.com/biezhi [著者]は最近APIを翻訳し、 https://github.com/lets-blade/blade[GitHub上の英語でのプロジェクト]。
いつものように、https://github.com/eugenp/tutorials/tree/master/blade [GitHub]でサンプルのソースコードを見つけることができます。