1概要

このチュートリアルでは、Spring MVCフレームワークを使用して画像やその他のメディアを返す方法を説明します。


メッセージ変換



Content Negotiation

のように直接

HttpServletResponse

を操作することから始める方法をいくつか説明しますSpringの

Resource

抽象化。それぞれを詳しく見て、それぞれの長所と短所を説明します。


2

HttpServletResponse


を使用する

画像ダウンロードの最も基本的なアプローチは、

response

オブジェクトに対して直接働きかけ、純粋な

Servlet

実装を模倣することです。そして、それは以下のスニペットを使って実証されます:

@RequestMapping(value = "/image-manual-response", method = RequestMethod.GET)
public void getImageAsByteArray(HttpServletResponse response) throws IOException {
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    response.setContentType(MediaType.IMAGE__JPEG__VALUE);
    IOUtils.copy(in, response.getOutputStream());
}

次のリクエストを発行すると、ブラウザに画像が表示されます。

http://localhost:8080/spring-mvc-xml/image-manual-response.jpg

実装は

org.apache.commons.io

パッケージの

IOUtils

のおかげでかなり簡単で単純です。ただし、このアプローチの欠点は、潜在的な変化に対して頑健ではないことです。 MIMEタイプはハードコーディングされており、変換ロジックの変更やイメージの場所の外部化にはコードの変更が必要です。

次のセクションでは、より柔軟な方法について説明します。


3


HttpMessageConverterを使う



前のセクションでは、リンクを利用しない基本的なアプローチについて説明しました。/spring-httpmessageconverter-rest[メッセージ変換]および

Content Negotiation

Spring MVCの機能フレームワークこれらの機能をブートストラップするには、次のことが必要です。


  • @ ResponseBody

    アノテーションでコントローラメソッドにアノテーションを付ける

  • の戻り型に基づいて適切なメッセージコンバータを登録する

コントローラメソッド(バイト配列から画像ファイルへの正しい変換に必要な

ByteArrayHttpMessageConverter

など)


3.1. 構成

コンバータの設定を紹介するために、メソッドが

byte[]

型を返すたびにメッセージを変換する組み込みの

ByteArrayHttpMessageConverter

を使用します。


ByteArrayHttpMessageConverter

はデフォルトで登録されていますが、設定は他の組み込み型またはカスタムコンバータと同様です。

メッセージコンバータBeanを適用するには、Spring MVCコンテキスト内に適切な

MessageConverter

Beanを登録し、処理する必要があるメディアタイプを設定する必要があります。

<mvc:message-converters>

タグを使用してXMLで定義できます。

このタグは、次の例のように、

<mvc:annotation-driven>

タグ内に定義する必要があります。

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>image/jpeg</value>
                    <value>image/png</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

前述の構成部分は、

image/jpeg

および

image/png

応答コンテンツタイプに

ByteArrayHttpMessageConverter

を登録します。

<mvc:message-converters>

tagがmvc設定に存在しない場合は、デフォルトのコンバータセットが登録されます。

また、Java設定

を使用してメッセージコンバータ

を登録することもできます。

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(byteArrayHttpMessageConverter());
}

@Bean
public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
    ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
    arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
    return arrayHttpMessageConverter;
}

private List<MediaType> getSupportedMediaTypes() {
    List<MediaType> list = new ArrayList<MediaType>();
    list.add(MediaType.IMAGE__JPEG);
    list.add(MediaType.IMAGE__PNG);
    list.add(MediaType.APPLICATION__OCTET__STREAM);
    return list;
}


3.2. 実装

これでメディア要求を処理するメソッドを実装できます。前述したように、コントローラメソッドに

@ ResponseBody

アノテーションを付け、戻り型として

byte[]

を使用する必要があります。

@RequestMapping(value = "/image-byte-array", method = RequestMethod.GET)
public @ResponseBody byte[]getImageAsByteArray() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    return IOUtils.toByteArray(in);
}

メソッドをテストするには、ブラウザで次のリクエストを発行します。

http://localhost:8080/spring-mvc-xml/image-byte-array.jpg

利点として、このメソッドは__HttpServletResponseについて何も知りません。変換プロセスは、利用可能なコンバータの使用からカスタム変換の指定まで、高度に設定可能です。

応答のコンテンツタイプは、ハードコーディングする必要はなく、リンク:/path-mvc-content-negotiation-json-xml[negotiated]で、要求パスのサフィックス

.jpg

に基づいています。

このアプローチの欠点は、データソース(ローカルファイル、外部ストレージなど)から画像を取得するためのロジックを明示的に実装する必要があり、応答のヘッダーやステータスコードを制御できないことです。


4

ResponseEntity

クラスを使用する


Response Entity

にラップされた

byte[]

として画像を返すことができます。

Spring MVCの

ResponseEntity

は、HTTP Responseの本文だけでなく、ヘッダとresposeステータスコードの制御も可能にします。

このアプローチに従って、メソッドの戻り型を

ResponseEntity <byte[]>

として定義し、戻り値の

ResponseEntity

オブジェクトをメソッド本体に作成する必要があります。

@RequestMapping(value = "/image-response-entity", method = RequestMethod.GET)
public ResponseEntity<byte[]> getImageAsResponseEntity() {
    HttpHeaders headers = new HttpHeaders();
    InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
    byte[]media = IOUtils.toByteArray(in);
    headers.setCacheControl(CacheControl.noCache().getHeaderValue());

    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
    return responseEntity;
}


ResponseEntity

を使用すると、特定のリクエストに対するレスポンスコードを設定できます。

応答コードを明示的に設定することは、例外的なイベントが発生した場合に特に役立ちます。画像が見つからなかった場合(

FileNotFoundException

)または破損している場合(

IOException)このような場合、必要なのはレスポンスコードを設定することだけです。

new ResponseEntity <>(null、ヘッダー、HttpStatus.NOT

FOUND)、

適切なcatchブロック内。

さらに、レスポンスに特定のヘッダを設定する必要がある場合、この方法はパラメータとしてメソッドによって受け入れられる

HttpServletResponse

オブジェクトを使用してヘッダを設定するよりも簡単です。メソッドのシグネチャを明確かつ的確にします。


5

Resource

クラスを使用して画像を返す

最後に、

Resource

オブジェクトの形式で画像を返すことができます。


Resource

インタフェースは、低レベルのリソースへのアクセスを抽象化するためのインタフェースです。これはSpringで標準の

java.net.URL

クラスのより有能な代替品として導入されました。明示的にそれらを取得するコードを書く必要なしにそれは異なるタイプのリソース(ローカルファイル、リモートファイル、クラスパスリソース)への簡単なアクセスを可能にします。

この方法を使用するには、メソッドの戻り型を

Resource

に設定し、メソッドに

@ ResponseBody

アノテーションを付ける必要があります。


5.1. 実装

@ResponseBody
@RequestMapping(value = "/image-resource", method = RequestMethod.GET)
public Resource getImageAsResource() {
   return new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");
}

あるいは、レスポンスヘッダをもっと制御したい場合は、

@RequestMapping(value = "/image-resource", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Resource> getImageAsResource() {
    HttpHeaders headers = new HttpHeaders();
    Resource resource =
      new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");
    return new ResponseEntity<>(resource, headers, HttpStatus.OK);
}

このアプローチを使用すると、

ResourceLoader

インターフェース実装を使用してロードできるリソースとして画像を扱います。そのような場合、あなたはあなたのイメージの正確な位置から抽象化し、

ResourceLoader

はそれがどこからロードされるかを決定します。

これは、設定を使用してイメージの場所を制御し、ファイルロードコードを書く必要性を排除するための一般的なアプローチを提供します。


6. 結論

前述のアプローチの中では、フレームワークのメッセージ変換機能から恩恵を受けるアプローチを使用するよりも、基本的なアプローチから始めました。また、応答オブジェクトを直接処理せずに、応答コードと応答ヘッダーを設定する方法についても説明しました。

最後に、イメージの場所から見た柔軟性が追加されました。イメージをどこから取得するかは、その場で変更するのが簡単な構成で定義されているためです。

チュートリアルに続くサンプルコードはhttps://github.com/eugenp/tutorials/tree/master/spring-mvc-xml[GitHub]で入手可能です。