第146章 SERVLET


Servlet コンポーネント

servlet: コンポーネントは、HTTP エンドポイント に到達した HTTP リクエストを消費するために HTTP ベースのエンドポイントを提供し、このエンドポイントは公開されたサーブレットにバインドされます。
Maven ユーザーは、このコンポーネントの pom.xml に以下の依存関係を追加する必要があります。
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-servlet</artifactId>
    <version>x.x.x</version>
    <\!-\- use the same version as your Camel core version \-->
</dependency>
Copy to Clipboard Toggle word wrap

Camel on EAP デプロイメント

このコンポーネントは、Red Hat JBoss Enterprise Application Platform (JBoss EAP) コンテナー上で簡素化されたデプロイメントモデルを提供する Camel on EAP (Wildfly Camel) フレームワークによってサポートされます。このモデルの詳細は、Deploying into a Web Server の Apache Camel on JBoss EAP の章を参照してください

URI 形式

servlet://relative_path[?options]
Copy to Clipboard Toggle word wrap
URI にクエリーオプションは ?option=value&option=value&.. の形式で追加できます。

オプション

Expand
名前 デフォルト値 説明
httpBindingRef null レジストリーの org.apache.camel.component.http.HttpBinding への参照。HttpBinding 実装を使用して、応答の作成方法をカスタマイズできます。
httpBinding null Camel 2.16: レジストリー の org.apache.camel.component.http.HttpBinding への 参照HttpBinding 実装を使用して、応答の作成方法をカスタマイズできます。
matchOnUriPrefix false 完全に一致するものが見つからない場合に、CamelServlet が URI 接頭辞と一致することでターゲットコンシューマーの検索を試みるかどうか。
servletName CamelServlet サーブレットエンドポイントがバインドするサーブレット名を指定します。サーブレット名が指定されていない場合、サーブレットエンドポイントは最初に公開されたサーブレットにバインドされます。
httpMethodRestrict null Camel 2.11: (コンシューマーのみ) HttpMethod が一致する場合にのみ消費できるようにするために使用されます(例: GET/POST/PUT など)。Camel 2.15 以降では、複数のメソッドをコンマで区切って指定できます。

メッセージヘッダー

Apache Camel は、HTTP コンポーネントと同じメッセージヘッダーを適用します。
Apache Camel は すべてrequest.parameter および request.headers も設定します。たとえば、クライアント要求に URL http://myserver/myserver?orderid=123 がある場合、エクスチェンジには orderid という名前のヘッダー(値が 123)が含まれます。

使用方法

Servlet コンポーネントによって生成されたエンドポイントからのみ消費できます。そのため、Apache Camel ルートへの入力としてのみ使用する必要があります。他の HTTP エンドポイントに対して HTTP 要求を発行するには、HTTP コンポーネントを使用します。

Camel JAR のアプリケーションサーバーブートクラスパスへの配置

アプリケーションサーバーのブートクラスパス(通常は lib ディレクトリー内)に camel-corecamel-servlet などの Camel JAR を配置する場合、サーブレットマッピングリストがアプリケーションサーバーの複数のデプロイ済み Camel アプリケーション間で共有されることに注意してください。
通常、アプリケーションサーバーのブートクラスパスに Camel JAR を配置することはベストプラクティスではありません。
したがって、このような状況では、各 Camel アプリケーションでカスタムおよび一意のサーブレット名を定義する 必要があり ます。たとえば、web.xml では以下を定義します。
<servlet>
  <servlet-name>MyServlet</servlet-name>
  <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>MyServlet</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>
Copy to Clipboard Toggle word wrap
Camel エンドポイントにもサーブレット名が含まれる
<route>
  <from uri="servlet://foo?servletName=MyServlet"/>
  ...
</route>
Copy to Clipboard Toggle word wrap
Camel 2.11 以降、Camel はこの重複を検出し、アプリケーションの起動に失敗します。以下のようにサーブレット init-parameter ignoreDuplicateServletName を true に設定すると、この重複を無視するように制御できます。
  <servlet>
    <servlet-name>CamelServlet</servlet-name>
    <display-name>Camel Http Transport Servlet</display-name>
    <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
    <init-param>
      <param-name>ignoreDuplicateServletName</param-name>
      <param-value>true</param-value>
    </init-param>
  </servlet>
Copy to Clipboard Toggle word wrap
しかし、この重複の競合や副次 的な副次的な影響を回避するために、各 Camel アプリケーションに一意の servlet-name を使用することを強くお勧め します。

重要
Camel 2.7 以降、Spring Web アプリケーションで サーブレット を簡単に使用できます。詳細は、サーブレット Tomcat の例 を参照してください。
この例では、http://localhost:8080/camel/services/hello で HTTP サービスを公開するルートを定義します。まず、通常の Web コンテナーまたは OSGi サービスを介して CamelHttpTransportServlet を公開する必要があります。Web.xml ファイルを使用して、以下のように CamelHttpTransportServlet を公開します。
<web-app>

  <servlet>
    <servlet-name>CamelServlet</servlet-name>
    <display-name>Camel Http Transport Servlet</display-name>
    <servlet-class>
        org.apache.camel.component.servlet.CamelHttpTransportServlet
    </servlet-class>
    
  </servlet>

  <servlet-mapping>
    <servlet-name>CamelServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

</web-app>
Copy to Clipboard Toggle word wrap
次に、以下のようにルートを定義できます。
from("servlet:///hello?matchOnUriPrefix=true").process(new Processor() {
    public void process(Exchange exchange) throws Exception {                    
        String contentType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);
        String path = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class);
        path = path.substring(path.lastIndexOf("/"));

        assertEquals("Get a wrong content type", CONTENT_TYPE, contentType);
        // assert camel http header
        String charsetEncoding = exchange.getIn().getHeader(Exchange.HTTP_CHARACTER_ENCODING, String.class);
        assertEquals("Get a wrong charset name from the message heaer", "UTF-8", charsetEncoding);
        // assert exchange charset
        assertEquals("Get a wrong charset naem from the exchange property", "UTF-8", exchange.getProperty(Exchange.CHARSET_NAME));
        exchange.getOut().setHeader(Exchange.CONTENT_TYPE, contentType + "; charset=UTF-8");                        
        exchange.getOut().setHeader("PATH", path);
        exchange.getOut().setBody("<b>Hello World</b>");
    }
});
Copy to Clipboard Toggle word wrap
camel-servlet エンドポイントの相対パスの指定
Http トランスポートをパブリッシュされたサーブレットとバインディングし、サーブレットのアプリケーションコンテキストパスを認識しないため、camel-servlet エンドポイントは相対パスを使用してエンドポイントの URL を指定します。クライアントはサーブレットパブリッシュアドレス ("http://localhost:8080/camel/services")+ RELATIVE_PATH ("/hello") を介して camel-servlet エンドポイントにアクセスできます。

Spring 3.x を使用する場合の例

スタンドアロン Apache Camel パッケージには、Tomcat Web コンテナーに Servlet コンポーネントをデプロイする方法を示すデモが含まれています。デモンストレーションは examples/camel-example-servlet-tomcat ディレクトリーにあります。Web コンテナーに Servlet コンポーネントをデプロイする場合は、WEB-INF/web.xml ファイルに Spring ContextLoaderListener インスタンスを作成して、Spring アプリケーションコンテキストを明示的に作成する必要があります。
たとえば、camel-config.xml ファイルから Spring 定義( camelContext およびルート定義を含む)を読み込む Spring アプリケーションコンテキストを作成するには、以下のように web.xml ファイルを定義します。
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>My Web Application</display-name>

    <!-- location of spring xml files -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:camel-config.xml</param-value>
    </context-param>

    <!-- the listener that kick-starts Spring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Camel servlet -->
    <servlet>
        <servlet-name>CamelServlet</servlet-name>
        <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Camel servlet mapping -->
    <servlet-mapping>
        <servlet-name>CamelServlet</servlet-name>
        <url-pattern>/camel/*</url-pattern>
    </servlet-mapping>

</web-app>
Copy to Clipboard Toggle word wrap

Spring 2.x を使用する場合の例

Camel/Spring アプリケーションで Servlet コンポーネントを使用する場合は、Servlet コンポーネントの起動 に Spring ApplicationContext をロードする必要があります。これは、ContextLoaderListener の代わりに Spring の ContextLoaderServlet を使用して実行できます。その場合、以下のように CamelHttpTransportServlet の後に ContextLoaderServlet を起動する必要があります。
<web-app>
  <servlet> 
        <servlet-name>CamelServlet</servlet-name> 
        <servlet-class> 
            org.apache.camel.component.servlet.CamelHttpTransportServlet 
        </servlet-class> 
        <load-on-startup>1</load-on-startup> 
  </servlet> 
  <servlet> 
        <servlet-name>SpringApplicationContext</servlet-name> 
        <servlet-class> 
            org.springframework.web.context.ContextLoaderServlet 
        </servlet-class> 
        <load-on-startup>2</load-on-startup> 
  </servlet> 
<web-app>
Copy to Clipboard Toggle word wrap

OSGi を使用する場合の例

Camel 2.6.0 以降では、CamelHttpTransportServlet を OSGi サービスとして公開し、以下のような SpringDM を利用して OSGi サービスとして公開できます。
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
    <bean id="camelServlet" class="org.apache.camel.component.servlet.CamelHttpTransportServlet"/>
    
    <!-- 
        Enlist it in OSGi service registry 
        This will cause two things:
        1) As the pax web whiteboard extender is running the CamelServlet will
           be registered with the OSGi HTTP Service
        2) It will trigger the HttpRegistry in other bundles so the servlet is
           made known there too
    -->
    <service ref="camelServlet">
        <interfaces>
            <value>javax.servlet.Servlet</value>
            <value>org.apache.camel.component.http.CamelServlet</value>
        </interfaces>
        <service-properties>
            <entry key="alias" value="/camel/services" />
            <entry key="matchOnUriPrefix" value="true" />
            <entry key="servlet-name" value="CamelServlet"/>
        </service-properties>
    </service>

</blueprint>
Copy to Clipboard Toggle word wrap
次に、以下のように Camel ルートでこのサービスを使用します。
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:camel="http://camel.apache.org/schema/blueprint">

    <reference id="servletref" interface="org.apache.camel.component.http.CamelServlet">
          <reference-listener bind-method="register" unbind-method="unregister">
             <ref component-id="httpRegistry"/>
          </reference-listener>
    </reference>
    
    <bean id="httpRegistry" class="org.apache.camel.component.servlet.DefaultHttpRegistry"/>
        
    <bean id="servlet" class="org.apache.camel.component.servlet.ServletComponent">
        <property name="httpRegistry" ref="httpRegistry" />
    </bean>

    <bean id="servletProcessor" class="org.apache.camel.itest.osgi.servlet.ServletProcessor" />

    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
        <route>
            <!-- notice how we can use the servlet scheme which is that osgi:reference above -->
            <from uri="servlet:///hello"/>
            <process ref="servletProcessor"/>
        </route>
    </camelContext>

</blueprint>
Copy to Clipboard Toggle word wrap
または、Camel 2.6 より前 - Activator を使用して、OSGi プラットフォームで CamelHttpTransportServlet を公開できます。
import java.util.Dictionary;
import java.util.Hashtable;

import org.apache.camel.component.servlet.CamelHttpTransportServlet;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.osgi.context.BundleContextAware;

public final class ServletActivator implements BundleActivator, BundleContextAware {
    private static final transient Logger LOG = LoggerFactory.getLogger(ServletActivator.class);
    private static boolean registerService;
    
    /**
     * HttpService reference.
     */
    private ServiceReference httpServiceRef;
    
    /**
     * Called when the OSGi framework starts our bundle
     */
    public void start(BundleContext bc) throws Exception {
        registerServlet(bc);
    }

    /**
     * Called when the OSGi framework stops our bundle
     */
    public void stop(BundleContext bc) throws Exception {
        if (httpServiceRef != null) {
            bc.ungetService(httpServiceRef);
            httpServiceRef = null;
        }
    }
    
    protected void registerServlet(BundleContext bundleContext) throws Exception {
        httpServiceRef = bundleContext.getServiceReference(HttpService.class.getName());
        
        if (httpServiceRef != null && !registerService) {
            LOG.info("Register the servlet service");
            final HttpService httpService = (HttpService)bundleContext.getService(httpServiceRef);
            if (httpService != null) {
                // create a default context to share between registrations
                final HttpContext httpContext = httpService.createDefaultHttpContext();
                // register the hello world servlet
                final Dictionary<String, String> initParams = new Hashtable<String, String>();
                initParams.put("matchOnUriPrefix", "false");
                initParams.put("servlet-name", "CamelServlet");
                httpService.registerServlet("/camel/services", // alias
                    new CamelHttpTransportServlet(), // register servlet
                    initParams, // init params
                    httpContext // http context
                );
                registerService = true;
            }
        }
    }

    public void setBundleContext(BundleContext bc) {
        try {
            registerServlet(bc);
        } catch (Exception e) {
            LOG.error("Cannot register the servlet, the reason is " + e);
        }
    }

}
Copy to Clipboard Toggle word wrap
トップに戻る
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2025 Red Hat