1概要

Java EEアノテーションは、アプリケーションコンポーネントがコンテナ内でどのように振る舞うべきかを指定できるようにすることで開発者の生活を楽にします。これらはXML記述子の現代的な代替手段であり、基本的には定型コードを回避することを可能にします。

この記事では、Java EE 7のServlet API 3.1で導入されたアノテーションに焦点を当てます。それらの目的を調べ、それらの使用法を調べます。


2ウェブ注釈

Servlet API 3.1では、

Servlet

クラスで使用できる新しい一連の注釈型が導入されました。


  • @ WebServlet


  • @ WebInitParam


  • @ WebFilter


  • @ WebListener


  • @ ServletSecurity


  • @ HttpConstraint


  • @ HttpMethodConstraint


  • @ MultipartConfig

次のセクションでそれらを詳細に調べます。


3

@ WebServlet


簡単に言うと、このアノテーションはサーブレットとしてJavaクラスを宣言することを可能にします


_:

_

@WebServlet("/account")
public class AccountServlet extends javax.servlet.http.HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
       //...
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
       //...
    }
}


3.1.

@ WebServlet

アノテーション

の属性を使用する


@ WebServlet

には、サーブレットをカスタマイズするための一連の属性があります。


  • name

  • 説明


  • urlPatterns


  • initParams

以下の例に示すようにこれらを使用できます。

@WebServlet(
  name = "BankAccountServlet",
  description = "Represents a Bank Account and it's transactions",
  urlPatterns = {"/account", "/bankAccount" },
  initParams = { @WebInitParam(name = "type", value = "savings")})
public class AccountServlet extends javax.servlet.http.HttpServlet {

    String accountType = null;

    public void init(ServletConfig config) throws ServletException {
       //...
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
       //...
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
       //...
    }
}


name

属性は、デフォルトの完全修飾クラス名であるデフォルトのサーブレット名をオーバーライドします。サーブレットが何をするのかを説明したい場合は、

description

属性を使用できます。


urlPatterns

属性は、サーブレットが使用可能なURLを指定するために使用されます(コード例に示すように、この属性に複数の値を指定できます)。


4

@ WebInitParam


このアノテーションは、

@ WebServlet

アノテーションの

initParams

属性とサーブレットの初期化パラメータとともに使用されます。

この例では、サーブレット初期化パラメータ

type

を ‘savings’の値に設定します。

@WebServlet(
  name = "BankAccountServlet",
  description = "Represents a Bank Account and it's transactions",
  urlPatterns = {"/account", "/bankAccount" },
  initParams = { @WebInitParam(name = "type", value = "savings")})
public class AccountServlet extends javax.servlet.http.HttpServlet {

    String accountType = null;

    public void init(ServletConfig config) throws ServletException {
        accountType = config.getInitParameter("type");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
       //...
    }
}

5.

@ WebFilter

サーブレットの内部ロジックに触れずにサーブレットの要求と応答を変更したい場合は、WebFilterアノテーションを使用できます。 URLパターンを指定することで、フィルタをサーブレットまたはサーブレットのグループと静的コンテンツに関連付けることができます。

以下の例では、ログインページへの不正アクセスをリダイレクトするために

@ WebFilter

アノテーションを使用しています。

@WebFilter(
  urlPatterns = "/account/** ",
  filterName = "LoggingFilter",
  description = "Filter all account transaction URLs")
public class LogInFilter implements javax.servlet.Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(
        ServletRequest request, ServletResponse response, FilterChain chain)
          throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        res.sendRedirect(req.getContextPath() + "/login.jsp");
        chain.doFilter(request, response);
    }

    public void destroy() {
    }

}


6.

@ WebListener


サーブレットとそのリクエストがいつどのように初期化または変更されるかについての知識または制御が必要な場合は、

@ WebListener

アノテーションを使用できます。

Webリスナを書くためには、次のインタフェースを1つ以上拡張する必要があります。


  • ServletContextListener – for

    に関する通知


ServletContext

ライフサイクル
** __ServletContextAttributeListener – 通知時の通知


ServletContext

属性が変更されました
**

ServletRequestListener – のリクエストがあるたびにfor

通知

リソースが作られる
** __ServletRequestAttributeListener – 通知時の通知


ServletRequest

で属性が追加、削除、または変更された
** __HttpSessionListener – 新しいセッションが確立したときの通知

作成され破壊された
** HttpSessionAttributeListener – 新しいときの通知用

セッションに属性を追加または削除しています

以下は

ServletContextListener

を使用してWebアプリケーションを構成する方法の例です。

@WebListener
public class BankAppServletContextListener
  implements ServletContextListener {

    public void contextInitialized(ServletContextEvent sce) {
        sce.getServletContext().setAttribute("ATTR__DEFAULT__LANGUAGE", "english");
    }

    public void contextDestroyed(ServletContextEvent sce) {
       //...
    }
}


7.

@ ServletSecurity


ロール、アクセス制御、認証要件など、サーブレットのセキュリティモデルを指定する場合は、アノテーション

@ ServletSecurity

を使用します。

この例では、

@ ServletSecurity

アノテーションを使用して

AccountServlet

へのアクセスを制限します。

@WebServlet(
  name = "BankAccountServlet",
  description = "Represents a Bank Account and it's transactions",
  urlPatterns = {"/account", "/bankAccount" },
  initParams = { @WebInitParam(name = "type", value = "savings")})
@ServletSecurity(
  value = @HttpConstraint(rolesAllowed = {"Member"}),
  httpMethodConstraints = {@HttpMethodConstraint(value = "POST", rolesAllowed = {"Admin"})})
public class AccountServlet extends javax.servlet.http.HttpServlet {

    String accountType = null;

    public void init(ServletConfig config) throws ServletException {
       //...
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
      //...
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
        double accountBalance = 1000d;

        String paramDepositAmt = request.getParameter("dep");
        double depositAmt = Double.parseDouble(paramDepositAmt);
        accountBalance = accountBalance + depositAmt;

        PrintWriter writer = response.getWriter();
        writer.println("<html> Balance of " + accountType + " account is: " + accountBalance
        + "</html>");
        writer.flush();
    }
}

この場合、

AccountServletを呼び出すと、ブラウザは

有効なユーザー名とパスワードを入力するためのユーザーのログイン画面をポップアップします。


@ HttpConstraint

および

@ HttpMethodConstraint

アノテーションを使用して、

@ ServletSecurity

アノテーションの

value

および

httpMethodConstraints

属性の値を指定できます。


@ HttpConstraint

アノテーションはすべてのHTTPメソッドに適用されます。つまり、デフォルトのセキュリティ制約を指定します。


@ HttpConstraint

には3つの属性があります。




  • ロール許可


  • 輸送保証

これらの属性のうち、最も一般的に使用される属性は

rolesAllowed

です。上記のサンプルコードスニペットでは、ロール

Member

に属するユーザーはすべてのHTTPメソッドを呼び出すことが許可されています。


@ HttpMethodConstraint

アノテーションを使用すると、特定のHTTPメソッドのセキュリティ制約を指定できます。


@ HttpMethodConstraint

には以下の属性があります。




  • emptyRoleSemantic


  • ロール許可


  • 輸送保証

上記のサンプルコードスニペットでは、

Admin

ロールに属するユーザーに対してのみ

doPost

メソッドが制限され、

Admin

ユーザーのみがデポジット機能を実行できるようになっています。


8

@ MultipartConfig


この注釈は、multipart/form-data要求を処理するためにサーブレットに注釈を付ける必要がある場合に使用されます(通常はファイルアップロードサーブレットに使用されます)。

これにより、

HttpServletRequest



getParts()

メソッドと

getPart(name)

メソッドを使用して、個々の部分だけでなくすべての部分にアクセスできます。

アップロードされたファイルは、Partオブジェクトの

write(fileName)

を呼び出すことでディスクに書き込むことができます。

それでは、その使い方を示すサンプルサーブレット

UploadCustomerDocumentsServlet

を見てみましょう。

@WebServlet(urlPatterns = { "/uploadCustDocs" })
@MultipartConfig(
  fileSizeThreshold = 1024 **  1024 **  20,
  maxFileSize = 1024 **  1024 **  20,
  maxRequestSize = 1024 **  1024 **  25,
  location = "./custDocs")
public class UploadCustomerDocumentsServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
        for (Part part : request.getParts()) {
            part.write("myFile");
        }
    }

}


@ MultipartConfig

には4つの属性があります。


  • fileSizeThreshold

    – 保存時のサイズのしきい値です。

ファイルを一時的にアップロードしました。アップロードされたファイルのサイズが
このしきい値は、ディスクに保存されます。それ以外の場合、ファイルは
メモリに格納されています(バイト単位のサイズ)
**

maxFileSize

– これはアップロードされたファイルの最大サイズです(サイズは

バイト)
**

maxRequestSize

– これはリクエストの最大サイズです。

アップロードされたファイルと他のフォームデータ(サイズ(バイト))の両方
**

location

– アップロードされたファイルが保存されているディレクトリです。


9結論

この記事では、Servlet API 3.1で導入されたいくつかのJava EEアノテーションとそれらの目的および使用法について調べました。

この記事に関連するソースコードはhttps://github.com/eugenp/tutorials/tree/master/jee-7/src/main/java/com/baeldung/javaeeannotations[GitHubで入手]