連載
» 2011年04月12日 00時00分 公開

Tomcat 7の新機能で何ができるようになるのか?(1):Tomcat 7も対応したServlet 3.0の6つの主な変更点 (3/3)

[藤野圭一,NTT OSSセンタ]
前のページへ 1|2|3       

【2】プログラムによるWebアプリケーションの拡張

 Servlet 3.0ではServletやFilter、およびそれらのURLマッピングをプログラムから動的に登録し、Webアプリケーションを拡張できます。拡張メソッドは、そのアプリケーションの初期化中でのみ、呼び出すことが可能です。

 そのため、ServletContextListenerのcontexInitializedメソッドか、ServletContainerInitializerのonStartupメソッドのいずれかのみで利用できます。

 利用可能なAPIの一部を紹介します。これらAPIはServletContextから呼び出せます。

Servletを生成するメソッド
public <T extends Servlet> T createServlet(Class<T> c) throws ServletException

Servletを追加するメソッド
public ServletRegistration.Dynamic addServlet(String servletName, String className)

public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)

public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass)

Filterを生成するメソッド
public <T extends Filter> T createFilter(Class<T> c) throws ServletException

Filterを追加するメソッド
public FilterRegistration.Dynamic addFilter(String filterName, String className)

public FilterRegistration.Dynamic addFilter(String filterName, Filter filter)

public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass)

Listenerを生成するメソッド
public <T extends EventListener> T createListener(Class<T> c) throws ServletException

Listenerを追加するメソッド
public void addListener(Class<? extends EventListener> listenerClass)

public void addListener(String className)

 addServletメソッドやaddFilterメソッドはServletRegistration.DynamicやFilterRegistration.Dynamicを返却します。開発者は、これらRegistrationインターフェイスを利用してServletやFilterのマッピングや初期パラメータの追加などを行います。

 ServletRegistration.DynamicインターフェイスとFilterRegistration.DynamicインターフェイスのAPIの一部を、以下に記載します。

  • ServletRegistration.Dynamicで利用可能なインターフェイス
URLパターンでServletをマッピング
public Set<String> addMapping(String... urlPatterns)

loadOnStartupの設定
public void setLoadOnStartup(int loadOnStartup)

初期パラメータの設定
public boolean setInitParameter(String name, String value)

非同期サポートの設定
public void setAsyncSupported(boolean isAsyncSupported)

  • FilterRegistration.Dynamicで利用可能なインターフェイス
Servlet名でFilterをマッピング
public void addMappingForServletNames(
EnumSet<DispatcherType> dispatcherTypes,
boolean isMatchAfter, String... servletNames)

URLパターンでFilterをマッピング
addMappingForUrlPatterns(
EnumSet<DispatcherType> dispatcherTypes,
boolean isMatchAfter, String... urlPatterns)

初期パラメータの設定
public boolean setInitParameter(String name, String value)

非同期サポートの設定
public void setAsyncSupported(boolean isAsyncSupported)

 ServletContextListenerでの利用例は、こんな感じです。

@WebListener()
public class RegistServletContextListener implements
        ServletContextListener {
 
    @Override
    public void contextDestroyed(ServletContextEvent event) {
      // TODO
    }
 
    @Override
    public void contextInitialized(ServletContextEvent event) {
        ServletContext context = event.getServletContext();
        Servlet servlet = null;
        try {
            servlet = context.createServlet(TestServlet.class);//---[1]
        } catch (ServletException e) {
            // TODO
        }
        ServletRegistration reg = context.addServlet("config", servlet);//---[2]
        if (reg != null) {
            Set conflicts = reg.addMapping("/config1");//---[3]
            if (!conflicts.isEmpty()) {
                // TODO 
            }
        }
    }
}

 上記サンプルでは、[1]でTestServletクラスのインスタンスを生成し、【2]でコンテキストにTestServletインスタンスを登録します。

 [3]で返却されたServletRegistrationに「/config1」をマッピングすることで、TestServletが/config1のパスでアクセスできるようになります。

 もう1つ、ServletContainerInitializerでの利用例も載せておきます。

※ServletContainerInitializerはServlet 3.0から追加されたインターフェイスで、アプリケーションの初期化時にサービスプロバイダによって呼び出されます。

 まず、JARのサービスプロバイダにServletContainerInitializerを登録します。

  META-INF/services/javax.servlet.ServletContainerInitializer

 ServletContainerInitializerを実装します。

public class TestInitializer implements ServletContainerInitializer {
 
    @Override
    public void onStartup(Set<Class<?>> classes, ServletContext ctxt)
            throws ServletException {
        ServletRegistration reg = ctxt.addServlet("initialTest", "init.TestServlet");
        if (reg != null) {
            Set conflicts = reg.addMapping("/testpath1", "/testpath2");
            if (!conflicts.isEmpty()) {
                // TODO 
            }
        }
    }
}

 これら拡張メソッドを利用することで、Webコンテキスト初期化時にプログラムによって動的にWebアプリケーションを拡張できます。

【3】JSPのモジュール化

 Servlet 3.0では、JSPのモジュール化が追加されました。JARファイルの「META-INF/resources」配下に静的コンテンツやJSPを作成し、Webアプリケーションの「WEB-INF/lib」にJARを配置することで、それらのファイルにWebからアクセスできます。

図3 JSPのモジュール化 図3 JSPのモジュール化

 JSPを1つのJARに固めて利用できるので、ちょっと便利です。

Servlet 3.0の変更点は、まだまだある!

 今回はTomcat 7の紹介としてServlet 3.0のうち、EoDとモジュール化と拡張性を紹介しました。

 次回は、Servlet 3.0の変更点の紹介の続きとして、非同期処理、セキュリティ、Session Tracking、マルチパート対応について紹介する予定です。


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。