HTTPメッセージ変換器

13527 ワード

HTTPメッセージ変換器


ビューテンプレートからHTMLを生成して応答するのではなく、HTTP APIのように直接HTTPメッセージ本体からJSONデータを読み込んだり書き込んだりする場合は、HTTPメッセージ変換器を使用すると便利です.
Spring MVCは以下の場合にHTTPメッセージ変換器を自動的に適用する.
HTTPリクエスト:@ReqeCustBody,HttpEntity
HTTP応答:@RequestBody,HttpEntity
リクエストには@RequestBodyを扱うArgumentResolver,HttpEntityを扱うArgumentResolverがある.これらのArcgumentResolverは、HTTPメッセージ変換器を使用して必要なオブジェクトを生成します.
応答には,@ResponseBodyとHttpEntityを扱うReturnValue Handlerがある.ここでHTTPメッセージ変換器を呼び出して応答結果を生成する.
HTTPメッセージ変換器はインタフェースからなる.
public interface HttpMessageConverter<T> {

   boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);

   boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

   List<MediaType> getSupportedMediaTypes();

   default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
      return (canRead(clazz, null) || canWrite(clazz, null) ?
            getSupportedMediaTypes() : Collections.emptyList());
   }

   T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
         throws IOException, HttpMessageNotReadableException;

   void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
         throws IOException, HttpMessageNotWritableException;

}
canRead()およびcanWrite()メッセージ変換器がクラス、メディアタイプをサポートしているかどうかを確認します.
read()およびwrite()は、メッセージ変換器を介してメッセージを読み取り、書き込む機能である.
このインタフェースを実装したいくつかの変換器があり、いくつかの主要な実装器だけを理解しましょう.
ばね起動デフォルトメッセージ変換器
0 = ByteArrayHttpMessageConverter
1 = StringHttpMessageConverter
2 = MappingJackson2HttpMessageConverter
優先順位が低い.
ターゲットクラスタイプとメディアタイプをチェックして、それらを使用するかどうかを決定します.気に入らない場合は、次のメッセージコンバータに移動します.
ByteArrayHttpMessageConverter
byte[]タイプのデータを処理します.
クラスタイプ:byte[],メディアタイプ(コンテンツタイプ):*/*
要求例)@RequestBody byte[]data
応答例)@ResponseBody return byte[],書き込みメディアタイプ:アプリケーション/octet-stream
StringHttpMessageConverter
String文字でデータを処理する
カテゴリ:String、メディアタイプ(コンテンツタイプ):*/*
要求例)@Request Body String data
応答例)@ResponseBody return“OK”,書き込みメディアタイプ:test/plain
MappingJackson2HttpMessageConverter
アプリケーション/jsonを処理します.
クラスタイプ:オブジェクトまたはHashMap、メディアタイプ:アプリケーション/json
要求例)@Request Body HelloDataデータ
応答例)@ResponseBody return helloData,書き込みメディアタイプ:アプリケーション/json
たとえば、

StringHttpMessageConverter
content-type: application/json
@RequestMapping 
void hello(@RequetsBody String data) {}
//String 타입 스트링 값 data 담김
MappingJackson2HttpMessageConverter
content-type: application/json
@RequestMapping
void hello(@RequetsBody HelloData data) {}
//객체 타입 data에 MappingJackson2HttpMessageConverter 로 인해 json 변환해서 담김
?
content-type: text/html
@RequestMapping
void hello(@RequetsBody HelloData data) {}
//객체타입 확인후 미디어타입 이맞지않아서 오류 발생

HTTPメッセージ変換器の動作


HTTPリクエストデータの読み出し
HTTPリクエストが発行され、コントローラは@RequestBodyとHttpEntityパラメータを使用します.
メッセージ変換器はcanRead()を呼び出し、メッセージが読み取り可能かどうかを決定する.
ターゲットクラスタイプがサポートされているかどうか.
例)@RequestBodyのターゲットクラス:byte[],String,HelloData
HTTPリクエストのコンテンツタイプメディアタイプをサポートしているか
例)test/plain、アプリケーション/json、*/*
canRead()条件が満たされている場合は、read()を呼び出してオブジェクトを作成し、返します.
HTTP応答データの生成
この値はコントローラから@ResponseBodyとHttpEntityに戻ります.
メッセージコンバータはcanwrite()を呼び出し、メッセージが書き込まれるかどうかを決定する
ターゲットクラスタイプをサポートするかどうか
例)返されるターゲットクラス(byte[]、String、HelloData)
HTTPリクエストの受信メディアタイプがサポートされているかどうか(より正確には@ResquestMappingの製品)
例)test/plain、アプリケーション/json、*/*
canwrite()条件が満たされている場合、write()を呼び出してHTTPレスポンスメッセージ本体にメッセージを生成する.
HTTPメッセージ変換器はどこで使用しますか?
要求マッピングで使用します.
RequestMappingHandler Adapterは、コントローラを呼び出す前にArcgumentResolverを使用して、入力された要求情報をコントローラに必要なデータ型に変換します.
そして、応答データの送信時には、ReturnValue Handlerを使用してコントローラから返されたデータを変換して返します.

この過程でArcgumentResolverとReturnValueHandlerがデータを変換する際に使用するのがメッセージ変換器です
整理すると、
招待を受ける
HandlerMappingで対応するリクエストのHandlerを見つけます.
対応するハンドルを実行できるHandler Adapterを見つけます.
対応するHandler Adapterを実行します.
実行中のHandlerAdapterがR e q eustMappingHandlerAdapterである場合、ArcgumentResolverはコントローラを呼び出す前に要求データをコントローラに必要なデータに変換するように呼び出されます.
ArcgumentResolverは、呼び出し時にメッセージ変換器を使用してコントローラを必要なデータに変換し、値を返します.
変換したデータをコントローラに転送します.
コントローラは論理を実行して値を返します.
返される値は、ReturnValue Resolverがメッセージ変換器を使用してレスポンス結果を生成して返されます.

ArgumentResolver


ノイズベースのコントローラでは、複数のパラメータを使用できます.
HttpServiceletRequest、Model、@RequestParam、@ModelAttribute、@RequestBody、HttpEntityなど.
このようなことを可能にしたのがArcgumentResolverです.(正確には、HandleMethodArgumentResolverまたは略称ArgumNetResolver)
ノイズベースのコントローラを扱うrequestmappingHandler Adapterは,このArcgumNetResolverを呼び出すことでコントローラを生成するために必要な各種パラメータ値(オブジェクト)である.次に、これらのパラメータの値が準備されている場合、コントローラを呼び出して値を渡します.
Springは30以上のArgumNetResolverを提供します.
正確にはHandleMethodArgumentResolver、略称ArgumentResolver.

public interface HandlerMethodArgumentResolver {

boolean supportsParameter(MethodParameter parameter);

@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory 
binderFactory) throws Exception;

}

ArgumentResolverの動作


ArcgumentResolverのsupportsParameter()を呼び出して、パラメータがサポートされているかどうかを確認します.
サポートされている場合は、resolveArgument()を呼び出して実際のオブジェクトを生成します.このようにして生成されたオブジェクトは、コントローラを呼び出すときにスキップされます.
また、もしよろしければ、このインタフェースを自分で拡張して、ArcgumentResolverを作成することができます.

ReturnValueHandler


HandlerMethodReturnValueHandler略称ReturnValueHandler.
ArcgumentResolverと同様に、応答値を変換して処理します.
コントローラからStringビュー名を返すと、その動作の原因はReturnValue Handlerです.
スプリングは、ReturnValueHandlerを10個以上サポートします.
例)@ModelAndView、@ResponseBody、HttpEntity、String
リファレンス
Spring MVC 1編-バックエンドWeb開発のキーテクノロジー