1. 概要

この記事では、JavaでのWeb開発のコアとなる側面であるサーブレットについて説明します。

2. サーブレットとコンテナ

簡単に言うと、サーブレットは、要求を処理し、それらを処理して、応答で応答するクラスです。

たとえば、サーブレットを使用して、HTMLフォームを介してユーザーからの入力を収集し、データベースからレコードをクエリし、Webページを動的に作成できます。

サーブレットは、と呼ばれる別のJavaアプリケーションの制御下にあります。 サーブレットコンテナ。 Webサーバーで実行されているアプリケーションがリクエストを受信したとき サーバーはリクエストをサーブレットコンテナに渡します。サーブレットコンテナはリクエストをターゲットサーブレットに渡します。

3. Mavenの依存関係

Webアプリにサーブレットサポートを追加するには、javaxservlet-api依存関係が必要です。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
</dependency>

最新のMaven依存関係は、ここにあります。

もちろん、アプリをデプロイするサーブレットコンテナも設定する必要があります。 これは、TomcatにWARをデプロイする方法を開始するのに適した場所です。

4. サーブレットのライフサイクル

サーブレットのライフサイクルを定義する一連のメソッドを見ていきましょう。

4.1. init()

init メソッドは、1回だけ呼び出されるように設計されています。 サーブレットのインスタンスが存在しない場合、Webコンテナは次のようになります。

  1. サーブレットクラスをロードします
  2. サーブレットクラスのインスタンスを作成します
  3. initメソッドを呼び出して初期化します

init メソッドは、サーブレットが要求を受信する前に正常に完了する必要があります。 initメソッドがServletExceptionをスローするか、Webサーバーで定義された期間内に返されない場合、サーブレットコンテナはサーブレットをサービスに配置できません。

public void init() throws ServletException {
    // Initialization code like set up database etc....
}

4.2. service()

このメソッドは、サーブレットの init()メソッドが正常に完了した後にのみ呼び出されます

コンテナはservice()メソッドを呼び出してクライアントからのリクエストを処理し、HTTPリクエストタイプ( GET POST PUTを解釈します]、 DELETE など)、 doGet doPost doPut doDeleteなどを呼び出します。 必要に応じてメソッド。

public void service(ServletRequest request, ServletResponse response) 
  throws ServletException, IOException {
    // ...
}

4.3. destroy()

サーブレットをサービスから外すためにサーブレットコンテナによって呼び出されます。

このメソッドは、サーブレットの service メソッド内のすべてのスレッドが終了した後、またはタイムアウト期間が経過した後にのみ呼び出されます。 コンテナがこのメソッドを呼び出した後、サーブレットでserviceメソッドを再度呼び出すことはありません。

public void destroy() {
    // 
}

5. サーブレットの例

フォームを使用して情報を処理する完全な例を設定しましょう。

まず、マッピング /calculateServlet を使用してサーブレットを定義します。これにより、フォームによってPOSTされた情報がキャプチャされ、RequestDispatcherを使用して結果が返されます。

@WebServlet(name = "FormServlet", urlPatterns = "/calculateServlet")
public class FormServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response)
      throws ServletException, IOException {

        String height = request.getParameter("height");
        String weight = request.getParameter("weight");

        try {
            double bmi = calculateBMI(
              Double.parseDouble(weight), 
              Double.parseDouble(height));
            
            request.setAttribute("bmi", bmi);
            response.setHeader("Test", "Success");
            response.setHeader("BMI", String.valueOf(bmi));

            RequestDispatcher dispatcher 
              = request.getRequestDispatcher("index.jsp");
            dispatcher.forward(request, response);
        } catch (Exception e) {
            response.sendRedirect("index.jsp");
        }
    }

    private Double calculateBMI(Double weight, Double height) {
        return weight / (height * height);
    }
}

上記のように、 @WebServlet で注釈が付けられたクラスは、javax.servlet.http.HttpServletクラスを拡張する必要があります。 @WebServlet アノテーションは、JavaEE6以降でのみ使用可能であることに注意してください。

@WebServlet アノテーションは、デプロイメント時にコンテナによって処理され、対応するサーブレットが指定されたURLパターンで使用可能になります。 アノテーションを使用してURLパターンを定義することにより、サーブレットマッピングにweb.xmlという名前のXMLデプロイメント記述子を使用することを回避できることに注意してください。

アノテーションなしでサーブレットをマップしたい場合は、代わりに従来のweb.xmlを使用できます。

<web-app ...>

    <servlet>
       <servlet-name>FormServlet</servlet-name>
       <servlet-class>com.root.FormServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FormServlet</servlet-name>
        <url-pattern>/calculateServlet</url-pattern>
    </servlet-mapping>

</web-app>

次に、基本的なHTMLフォームを作成しましょう。

<form name="bmiForm" action="calculateServlet" method="POST">
    <table>
        <tr>
            <td>Your Weight (kg) :</td>
            <td><input type="text" name="weight"/></td>
        </tr>
        <tr>
            <td>Your Height (m) :</td>
            <td><input type="text" name="height"/></td>
        </tr>
        <th><input type="submit" value="Submit" name="find"/></th>
        <th><input type="reset" value="Reset" name="reset" /></th>
    </table>
    <h2>${bmi}</h2>
</form>

最後に、すべてが期待どおりに機能していることを確認するために、簡単なテストも作成しましょう。

public class FormServletLiveTest {

    @Test
    public void whenPostRequestUsingHttpClient_thenCorrect() 
      throws Exception {

        HttpClient client = new DefaultHttpClient();
        HttpPost method = new HttpPost(
          "http://localhost:8080/calculateServlet");

        List<BasicNameValuePair> nvps = new ArrayList<>();
        nvps.add(new BasicNameValuePair("height", String.valueOf(2)));
        nvps.add(new BasicNameValuePair("weight", String.valueOf(80)));

        method.setEntity(new UrlEncodedFormEntity(nvps));
        HttpResponse httpResponse = client.execute(method);

        assertEquals("Success", httpResponse
          .getHeaders("Test")[0].getValue());
        assertEquals("20.0", httpResponse
          .getHeaders("BMI")[0].getValue());
    }
}

6. サーブレット、HttpServlet、JSP

それを理解することが重要ですサーブレット技術はHTTPプロトコルに限定されません。

実際にはほとんどの場合そうですが、 Servlet は汎用インターフェースであり、 HttpServlet はそのインターフェースの拡張であり、doGetdoPostなど。

最後に、サーブレットテクノロジは、 JSP – JavaServer Pages 、SpringMVCなどの他の多くのWebテクノロジの主要な推進力でもあります。

7. 結論

このクイック記事では、JavaWebアプリケーションのサーブレットの基礎を紹介しました。

サンプルプロジェクトは、GitHubプロジェクトとしてダウンロードしてそのまま実行できます。