コンテキストとサーブレットの初期化パラメータ

1概要

Servlets は、サーブレットコンテナ内で実行されるプレーンなJavaクラスです。

HTTPサーブレット(特定の種類のサーブレット)は、Java Webアプリケーションの第一級の市民です。 HTTPサーブレットのAPIは、 クライアントサーバープロトコルで実装された 典型的な要求 - 処理 - 応答サイクルを通じてHTTP要求を処理することを目的としています。

さらに、サーブレットは、要求/応答パラメータの形式のキーと値のペアを使用して、クライアント(通常はWebブラウザ)とサーバーの間の対話を制御できます。

これらのパラメータは、初期化してアプリケーション全体のスコープ(コンテキストパラメータ)とサーブレット固有のスコープ(サーブレットパラメータ)にバインドできます。

このチュートリアルでは、コンテキストとサーブレットの初期化パラメータを定義してアクセスする方法を学びます。

** 2サーブレットパラメータの初期化

アノテーションと標準のデプロイメント記述子 - “ web.xml” ファイルを使用して、サーブレットパラメータを定義および初期化できます。これら2つの選択肢は相互に排他的ではないことに注意する価値があります。

これらの各オプションを詳しく調べてみましょう。

2.1. 注釈を使う

  • アノテーションでサーブレットパラメータを初期化することで、設定とソースコードを同じ場所に保つことができます。

このセクションでは、アノテーションを使用して特定のサーブレットにバインドされている初期化パラメータを定義してアクセスする方法を説明します。

そのために、プレーンなHTMLフォームを介してユーザーデータを収集する単純な UserServlet クラスを実装します。

まず、フォームをレンダリングするJSPファイルを見てみましょう。

<!DOCTYPE html>
<html>
    <head>
        <title>Context and Initialization Servlet Parameters</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <h2>Please fill the form below:</h2>
        <form action="${pageContext.request.contextPath}/userServlet" method="post">
            <label for="name"><strong>Name:</strong></label>
            <input type="text" name="name" id="name">
            <label for="email"><strong>Email:</strong></label>
            <input type="text" name="email" id="email">
            <input type="submit" value="Send">
        </form>
    </body>
</html>

EL (式言語)を使用して、フォームの action 属性をコーディングしたことに注意してください。これにより、サーバー内のアプリケーションファイルの場所に関係なく、常に “/userServlet” パスを指すことができます。

“ $ \ {pageContext.request.contextPath}” expression はフォームの動的URLを設定します。これは常にアプリケーションのコンテキストパス を基準にしています。

これが最初のサーブレット実装です。

@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"}, initParams={
@WebInitParam(name="name", value="Not provided"),
@WebInitParam(name="email", value="Not provided")}))
public class UserServlet extends HttpServlet {
   //...

    @Override
    protected void doPost(
      HttpServletRequest request,
      HttpServletResponse response)
      throws ServletException, IOException {
        processRequest(request, response);
        forwardRequest(request, response, "/WEB-INF/jsp/result.jsp");
    }

    protected void processRequest(
      HttpServletRequest request,
      HttpServletResponse response)
      throws ServletException, IOException {

        request.setAttribute("name", getRequestParameter(request, "name"));
        request.setAttribute("email", getRequestParameter(request, "email"));
    }

    protected void forwardRequest(
      HttpServletRequest request,
      HttpServletResponse response,
      String path)
      throws ServletException, IOException {
        request.getRequestDispatcher(path).forward(request, response);
    }

    protected String getRequestParameter(
      HttpServletRequest request,
      String name) {
        String param = request.getParameter(name);
        return !param.isEmpty() ? param : getInitParameter(name);
    }
}

この場合は、 initParams @ WebInitParam アノテーションを使って、2つのサーブレット初期化パラメータ name email を定義しました。

HTMLフォームからデータを取得するにはHttpServletRequestの getParameter() メソッドを使用し、サーブレット初期化パラメータにアクセスするには getInitParameter() メソッドを使用しました。

getRequestParameter() メソッドは、 name および email 要求パラメータが空の文字列かどうかを確認します。

それらが空の文字列の場合は、一致する初期化パラメータのデフォルト値が割り当てられます。

doPost() メソッドは最初に、ユーザーがHTMLフォームに入力した名前とEメール(ある場合)を取り出します。次に、リクエストパラメータを処理し、リクエストを “ result.jsp” ファイルに転送します。

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>User Data</title>
    </head>
    <body>
        <h2>User Information</h2>
        <p><strong>Name:</strong> ${name}</p>
        <p><strong>Email:</strong> ${email}</p>
    </body>
</html>

サンプルWebアプリケーションをhttp://tomcat.apache.org/[Apache Tomcat]などのアプリケーションサーバーにデプロイする場合[Oracle GlassFish]またはhttp://www.wildfly.org/[JBoss WidlFly]を実行して実行すると、最初にHTMLフォームページが表示されます。

ユーザーが name フィールドと email フィールドに入力してフォームを送信すると、データを出力します。

User Information
Name: the user's name
Email: the user's email

フォームが空白の場合、サーブレット初期化パラメータが表示されます。

User Information
Name: Not provided
Email: Not provided

この例では、アノテーションを使用してサーブレット初期化パラメータを定義する方法と、 getInitParameter() メソッドを使用してそれらにアクセスする方法を示しました。

2.2. 標準のデプロイメント記述子の使用

  • このアプローチは、アノテーションを使うものとは異なります。それは、設定とソースコードを互いに分離したままにすることを可能にするからです。

“ web.xml” ファイルを使用して初期化サーブレットパラメータを定義する方法を示すために、まず UserServlet クラスから initParam および @ WebInitParam アノテーションを削除します。

@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"})
public class UserServlet extends HttpServlet { ... }

次に、 “ web.xml” ファイルでサーブレット初期化パラメータを定義しましょう。

<?xml version="1.0" encoding="UTF-8"?>
<web-app
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app__3__1.xsd" version="3.1">
    <servlet>
        <display-name>UserServlet</display-name>
        <servlet-name>UserServlet</servlet-name>
        <init-param>
            <param-name>name</param-name>
            <param-value>Not provided</param-value>
        </init-param>
        <init-param>
            <param-name>email</param-name>
            <param-value>Not provided</param-value>
        </init-param>
    </servlet>
</web-app>

上記のように、 “ web.xml” ファイルを使用してサーブレット初期化パラメータを定義することは、単に <init-param>、 <param-name> 、および <param-value> タグを使用することになります。

さらに、上記の標準構造に準拠している限り、必要な数のサーブレットパラメータを定義することも可能です。

アプリケーションをサーバーに再デプロイして再実行すると、アノテーションを使用するバージョンと同じように動作するはずです。

** 3コンテキストパラメータの初期化

グローバルに共有し、Webアプリケーション全体でアクセスする必要がある不変データを定義する必要がある場合があります。

データの大域的な性質により、サーブレットの対応物に頼るのではなく、データを格納するためにアプリケーション全体のコンテキスト初期化パラメータを使用する必要があります。

注釈を使用してコンテキスト初期化パラメータを定義することはできませんが、 “ web.xml” ファイルでこれを行うことができます。

アプリケーションが実行されている国と地域のデフォルトのグローバル値をいくつか指定したいとします。

これを実現するには、いくつかのコンテキストパラメータを使います。

それに応じて “ web.xml” ファイルをリファクタリングしましょう:

<web-app
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
  http://xmlns.jcp.org/xml/ns/javaee/web-app__3__1.xsd" version="3.1">
    <context-param>
        <param-name>province</param-name>
        <param-value>Mendoza</param-value>
    </context-param>
    <context-param>
        <param-name>country</param-name>
        <param-value>Argentina</param-value>
    </context-param>
    <!-- Servlet initialization parameters -->
</web-app>

今回は、 <context-param>、<param-name>、 、および <param-value> タグを使用して、 province および country コンテキストパラメータを定義しました。

もちろん、これらのパラメータを取得して結果ページに渡すことができるように、 UserServlet クラスをリファクタリングする必要があります。

サーブレットの関連セクションは次のとおりです。

@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"})
public class UserServlet extends HttpServlet {
   //...

    protected void processRequest(
      HttpServletRequest request,
      HttpServletResponse response)
      throws ServletException, IOException {

        request.setAttribute("name", getRequestParameter(request, "name"));
        request.setAttribute("email", getRequestParameter(request, "email"));
        request.setAttribute("province", getContextParameter("province"));
        request.setAttribute("country", getContextParameter("country"));
    }

    protected String getContextParameter(String name) {-
        return getServletContext().getInitParameter(name);
    }
}

getContextParameter() メソッドの実装に注意してください。最初に getServletContext()を介してサーブレットコンテキストを取得し、次に getInitParameter()__メソッドを使用してコンテキストパラメータを取得します。

次に、サーブレット固有のパラメータとともにコンテキストパラメータを表示できるように、 “ result.jsp” ファイルをリファクタリングする必要があります。

<p><strong>Name:</strong> ${name}</p>
<p><strong>Email:</strong> ${email}</p>
<p><strong>Province:</strong> ${province}</p>
<p><strong>Country:</strong> ${country}</p>

最後に、アプリケーションを再デプロイしてもう一度実行します。

ユーザーがHTMLフォームに名前と電子メールを入力すると、コンテキストデータとともにこのデータが表示されます。

User Information
Name: the user's name
Email: the user's email
Province: Mendoza
Country: Argentina

そうでなければ、サーブレットとコンテキスト初期化パラメータを出力します。

User Information
Name: Not provided
Email: Not provided
Province: Mendoza
Country: Argentina

この例は工夫されていますが、コンテキスト初期化パラメータを使用して不変グローバルデータを格納する方法を示しています。

データは特定のサーブレットではなくアプリケーションコンテキストにバインドされているので、 getServletContext() メソッドと getInitParameter() メソッドを使用して、1つまたは複数のサーブレットからそれらにアクセスできます。

4結論

この記事では、コンテキストとサーブレットの初期化パラメータの重要な概念と、それらを定義してアノテーションと “ web.xml” ファイルを使用してアクセスする方法を学びました。

かなり以前から、JavaにはXML構成ファイルを取り除き、可能な限り注釈に移行するという強い傾向がありました。

CDI 、https://spring.io/[Spring]、http://hibernate.org/[Hibernate]にちょっと名前を挙げて、これの明白な例です。

それにもかかわらず、コンテキストとサーブレットの初期化パラメータを定義するために “ web.xml” ファイルを使用しても本質的に問題はありません。

Servlet API はこの傾向に向かってかなり速いペースで進化してきましたが、 定義するにはデプロイメント記述子を使用する必要があります。コンテキスト初期化パラメータ

いつものように、この記事に示されているすべてのコードサンプルはhttps://github.com/eugenp/tutorials/tree/master/javax-servlets/[GitHubで利用可能]で利用可能です。