2011年1月9日日曜日

102.3 リソースの登録 (Registering Resources)

リソースとは, 画像, 静的 HTML ページ, 音声, 動画, アプレット, 等を含むファイルのことである. リソースはバンドルによる処理を必要としない. リソースは, それが置かれている場所 (通常はバンドルのコードを含んでいる JAR ファイル) から, HTTP を使用して要求元に直接転送される.

A resource is a file containing images, static HTML pages, sounds, movies, applets, etc. Resources do not require any handling from the bundle. They are transferred directly from their source--usually the JAR file that contains the code for the bundle--to the requestor using HTTP.

32 ページの「サーブレットの登録」で説明したように, リソースをサーブレットオブジェクトで処理することもできる. しかしながら, HTTP でリソース転送をおこなうとすると, 各バンドルが非常に似通ったサーブレットオブジェクトを持つことになってしまう. このような重複を避けるため, リソースは, HttpService インターフェースを介して Http サービスに直接登録できるようになっている. HttpService インターフェースには, Http サービスの URI 名前空間にリソースを登録するためのメソッド registerResources(String,String,HttpContext) が定義されている.

Resources could be handled by Servlet objects as explained in Registering Servlets on page 32. Transferring a resource over HTTP, however, would require very similar Servlet objects for each bundle. To prevent this redundancy, resources can be registered directly with the Http Service via the HttpService interface. This HttpService interface defines the registerResources(String,String,HttpContext) method for registering a resource into the Http Service URI name-space.

一番目の引数は外部エイリアスで, Http サービスへの登録に際して, リソースがその場所に置かれる. 二番目の引数は内部プレフィックスで, リソースとバンドルの名前空間の対応をとるものである. 要求を受けた時, HttpService オブジェクトは, URI から外部エイリアスを取り除いてそれを内部プレフィックスで置き換え, そうしてできた新しい名前を用いて, HttpContext オブジェクトの getResource(String) メソッドを呼ばなければならない. HttpContext オブジェクトはさらに, リソースの MIME タイプを取得したり, 要求の認証をおこなうために使用される.

The first parameter is the external alias under which the resource is registered with the Http Service. The second parameter is an internal prefix to map this resource to the bundle's name-space. When a request is received, the HttpService object must remove the external alias from the URI, replace it with the internal prefix, and call the getResource(String) method with this new name on the associated HttpContext object. The HttpContext object is further used to get the MIME type of the resource and to authenticate the request.

リソースは java.net.URL オブジェクトとして返却される. Http サービスはその URL オブジェクトを読み込み, その内容を, 当該 HTTP リクエストの発信元へ転送しなければならない.

Resources are returned as a java.net.URL object. The Http Service must read from this URL object and transfer the content to the initiator of the HTTP request.

この戻り値の型が選ばれたのは, それが java.lang.Class.getResource(String resource) メソッドの戻り値の型と同じだからである. このメソッドは, 対象となっているクラスがロードされたのと同じ場所 (大抵はバンドルの JAR ファイルのパッケージディレクトリー) から, 直接リソースを取得することができる. このメソッドにより, パッケージに含まれているバンドルからのリソース取得が, 非常に使い勝手の良いものになる.

This return type was chosen because it matches the return type of the java.lang.Class.getResource(String resource) method. This method can retrieve resources directly from the same place as the one from which the class was loaded - often a package directory in the JAR file of the bundle. This method makes it very convenient to retrieve resources from the bundle that are contained in the package.

次のコード例は, registerResources メソッドの使用方法を示すものである.

The following example code demonstrates the use of the registerResources method:

    package com.acme;
    ...
    HttpContext context = new HttpContext() {
      public boolean handleSecurity(
        HttpServletRequest request,
        HttpServletResponse response
      ) throws IOException {
        return true;
      }

      public URL getResource(String name) {
        return getClass().getResource(name);
      }

      public String getMimeType(String name) {
        return null;
      }
    };

    getHttpService().registerResources {
      "/files",
      "www",
      context
    );
    ...
    getHttpService().unregister("/files");

この例では, エイリアス /files が Http サービスに登録されている. この名前空間下にあるリソースに対する要求は, www/[名前] という内部名を伴って HttpContext オブジェクトへと転送される. この例では Class.getResource(String) メソッドが使用されている. 内部名が "/" で始まってはいないので, JAR ファイルの "com/acme/www" ディレクトリー内のリソースへとマッピングが行われる. もし内部名が "/" で始まっていたなら, パッケージ名は前置されず, JAR ファイルのルートから検索がおこなわれる. 詳細については java.lang.Class.getResource(String) を参照のこと.

This example registers the alias /files on the Http Service. Requests for resources below this name-space are transferred to the HttpContext object with an internal name of www/[name]. This example uses the Class.getResource(String) method. Because the internal name does not start with a "/", it must map to a resource in the "com/acme/www" directory of the JAR file. If the internal name did start with a "/", the package name would not have to be prefixed and the JAR file would be searched from the root. Consult the java.lang.Class.getResource(String) method for more information.

上記例の場合, http://www.acme.com/files/myfile.html に対する要求は, バンドルの JAR ファイル内の "com/acme/www/myfile.html" にマッピングされなければならない.

In the example, a request for http://www.acme.com/files/myfile.html must map to the name "com/acme/www/myfile.html" which is in the bundle's JAR file.

getResource(String) メソッドの実装をより手の込んだものにするならば, 入力名でフィルタリングをおこなって返却するリソースに制限をかけたり, (そうすることがセキュリティーの実装において許容可能であれば) 入力名をファイルシステムにマッピングしたり, といったことができる.

More sophisticated implementations of the getResource(String) method could filter the input name, restricting the resources that may be returned or map the input name onto the file system (if the security implementation of this action are acceptable).

別の方法として, 下記の registerResources の呼び出しで例示されているように, リソース登録に際してデフォルトの HttpContext オブジェクトを使用することができる.

Alternatively, the resource registration could have used a default HttpContext object, as demonstrated in the following call to registerResources:

    getHttpService().registerResources(
      "/files",
      "/com/acme/www",
      null
    );

この場合, Http サービスの実装は, createDefaultHttpContext() メソッドを呼び, その戻り値を, registerResources メソッドの HttpContext 引数として使用する. デフォルトの実装では, Bundle.getResource(String) を用いて, リソース要求をバンドルのリソースへとマッピングしなければならない. 前出の例の場合, 今度は, リソースファイル群を含む JAR ファイル内のディレクトリーのフルパス名を内部名に指定しなければならない. パッケージ名を自動で前置するという処理は行われない.

In this case, the Http Service implementation would call the createDefaultHttpContext() method and use its return value as the HttpContext argument for the registerResources method. The default implementation must map the resource request to the bundle's resource, using Bundle.getResource(String). In the case of the previous example, however, the internal name must now specify the full path to the directory containing the resource files in the JAR file. No automatic prefixing of the package name is done.

デフォルトの HttpContext オブジェクトの getMimeType(String) メソッドの実装は, null を返すことにより, Http サービスが提供するデフォルトのマッピングを利用するようにすべきである. handleSecurity(HttpServletRequest,HttpServletResponse) では, 実装依存の方法で認証機構を実装することが許されている.

The getMimeType(String) implementation of the default HttpContext object should rely on the default mapping provided by the Http Service by returning null. Its handleSecurity(HttpServletRequest,HttpServletResponse) may implement an authentication mechanism that is implementation-dependent.