Spring MVCオブジェクト変換の説明

11787 ワード

Spring MVCの前に、HttpServertRequestパラメータオブジェクトをサーブレットで処理する必要がありますが、このオブジェクトのプロパティは共通タイプのオブジェクト(文字列など)で、処理が煩雑でエラーが発生しやすいため、Spring MVCではパラメータと戻り値を直接オブジェクトとして定義できます.たとえば、次のようになります.
まずオブジェクトを定義します.
@Data
public class User {

    private String id;
    private String name;

}

次にSpring MVCメソッドを定義します.
@RequestMapping(value = "/create-user", method = RequestMethod.POST)
public void createUser(@RequestBody User user) {
    LOGGER.debug("  :user = {}", user);
}

ここで,パラメータがUserタイプのオブジェクト,@RequestBody注記通知Spring MVCはhttpリクエストのbodyをUserオブジェクトに変換し,パラメータとして我々が書いたcreateUserメソッドを呼び出す.
パラメータをオブジェクトとして定義するほか、戻り値もオブジェクトとして定義できます.
@RequestMapping(value = "/find-user", method = RequestMethod.GET)
@ResponseBody
public User findUser() {
    return new User("01", "yw");
}

戻り値オブジェクトには、Spring MVCが戻り値オブジェクトを文字列に変換し、http応答メッセージのbody部分とすることを通知する@ResponseBody注記が必要です.
Spring MVCには、@RequestBody、@ResponseBody注記のほかに、その他の注記も用意されています.詳細については、関連ドキュメントの説明を参照してください.
Spring MVCはhttpメッセージとオブジェクトの変換をどのように行いますか?答えはHttpMessageConverter変換インタフェースです.
 
HttpMessageConverter
Spring MVCは仲介者のようにhttpメッセージ(すなわちHttpServertRequestとHttpServertResponse)の一方で@RequestMappingメソッドであり、Spring MVCの使命はhttpメッセージを自動的にオブジェクトに変換し、逆にオブジェクトを文字列に変換して返すことである.これらはすべてHttpMessageConverter変換インタフェースに依存します.Spring MVCには多くの実装が内蔵されており、各実装は1つのフォーマットのデータ変換に対応しており、ロードコンバータをオンデマンドで構成することができます.構成されていない場合はSpring MVCがデフォルトでロードされます.デフォルトでロードされている変換器については、W e b M v c C o n f i g u r ationSupport#addDefaultHttpMessageConvertersメソッドを参照してください.[Http Message Converters with the Spring Framework]も参照してください(http://www.baeldung.com/spring-httpmessageconverter-rest).
特に注意したいのは、Spring MVCが構成されている場合は構成のみがロードされ、構成されていない場合はデフォルトでロードされます.したがって、あなたの構成がデフォルト値の補完だと勘違いしないでください.
私たちは基本的に自分でコンバータを構成する必要はありません.デフォルトの構成を使用すれば十分です.必要に応じて次のように構成できます.
@Configuration
@EnableWebMvc
public class WeMvcConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(...);
    }
}

構成されているかどうかにかかわらず、実行時にどのコンバータがロードされているかを確認したほうがいいです.
@EventListener
public void on(ContextRefreshedEvent event) {
    RequestMappingHandlerAdapter requestMappingHandlerAdapter =     applicationContext.getBean(RequestMappingHandlerAdapter.class);
    List<?> messageConverters =     requestMappingHandlerAdapter.getMessageConverters();
    StringBuilder sb = new StringBuilder();
    sb.append("Spring    ").append(messageConverters.size()).append("        :").append(messageConverters.toString());
    LOGGER.info(sb.toString());
}

上記のイベントリスナーメソッドでは、Springの起動が完了すると、ロードされたすべてのコンバータが印刷出力されます.2つの実験をすることができます.1つは自分で構成しないこと、2つは自分で構成し、それぞれシステムを起動して、どのコンバータがロードされているかを見ることです.
 
JSON
システムがjsonコンバータをロードすれば、jsonメッセージを送信できます.
curl -X POST -H 'Content-Type: application/json' -d '{"id":"01","name":"yw"}' http://localhost:8080/create-user

呼び出しが成功しない場合は、システムがjson変換器をロードしていない可能性があります.Spring MVCのデフォルト構成はjackson-databindが存在する場合にのみjsonコンバータをロードします.
jackson-databind依存項目があるかどうかを確認してください.
mvn dependency:tree | find "jackson-databind"

存在しない場合は、次のように定義します.
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>

これによりSpring MVCはjsonコンバータを自動的にロードします.
jsonメッセージの送信に加えて、jsonメッセージを受信することもできます.
curl http://localhost:8080/find-user
{"id":"01","name":"yw"}

 
XML
jsonと同様にSpring MVCも変換器を用いてxmlメッセージの送信と受信を実現する.違いは、Spring MVCはjackson-databindのjson変換器のみをサポートしていますが、jaxbとjackson-databind-xmlの2つのxml変換器をサポートしており、どちらかを選択して使用することができます.
Spring MVCがjackson-databind-xmlを自動的に構成するには、この依存項目が必要です.依存項目が存在するかどうかを確認します.
mvn dependency:tree | find "jackson-databind-xml"

存在しない場合は、次のように定義します.
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

xmlメッセージを伝えることができます
curl -X POST -H 'Content-Type: application/xml' -d '<root><id>01</id><name>yw</name></root>' http://localhost:8080/create-user

 
データフォーマットの強制
上記のように、create-userメソッドではxmlメッセージもjsonメッセージも受信できますが、データフォーマットを制限したい場合があります.consumesパラメータを追加できます.
@RequestMapping(value = "/xml-create-user", consumes = {MediaType.APPLICATION_XML_VALUE}, method = RequestMethod.POST)
public void xmlCreateUser(@RequestBody User user) {
    LOGGER.debug("  :user = {}", user);
}

上記の例では、xml形式のメッセージのみを受信することを示します.そのため、jsonメッセージを再送信すると失敗します.
同様に、戻り値をxmlに制限することもできます.
@RequestMapping(value = "/xml-find-user", method = RequestMethod.GET, produces = {MediaType.APPLICATION_XML_VALUE})
@ResponseBody
public User xmlFindUser() {
    return new User("02", "yw");
}

xmlメッセージを受信できます.
curl http://localhost:8080/xml-find-user
<User xmlns=""><id>02</id><name>yw</name></xml>

 
Jackson XML
Spring MVCは、xml変換器としてjackson-databind-xmlをサポートし、返されるxmlを実際にテストします.
<User xmlns=""><id>01</id><name>yw</name></xml>

xmlns=""があります.このxmlnsには副作用はありませんが、気になる場合は依存項目を増やすことができます.
<dependency>
  <groupId>com.fasterxml.woodstox</groupId>
  <artifactId>woodstox-core</artifactId>
  <version>5.0.2</version>
</dependency>

その理由については[FasterXMLディスカッション](FasterXMLディスカッション)を参照してください.https://github.com/FasterXML/jackson-dataformat-xml/issues/32).
 
オブジェクト向け
上ではjsonとxmlを多く紹介しましたが、Spring MVCが私たちに与えたメリットは、それらの存在を無視することです.オブジェクトだけに注目して、jsonから来たのかxmlから来たのかを考える必要はありません.これらの下位のことはSpring MVCに任せましょう.同時に、私たち自身のオブジェクトをパラメータと戻り値として直接使用することで、ユニットテストが書きやすくなります.
 
練習する
1、もしあなたのシステムにjsonとxmlコンバータがある場合、RestTemplateコードとcurlツールで同じSpring MVCメソッドを呼び出すと、一つはxmlを返し、もう一つはjsonを返しますか?
@Test
public void test() {
    RestTemplate restTemplate = new RestTemplate();
    String s = restTemplate.getForObject("http://localhost:8080/find-user", String.class);
    System.out.println(s);
    // <User xmlns=""><id>01</id><name>yw</name></xml>
}

 
curl http://localhost:8080/find-user
{"id":"01","name":"yw"}

 
2、本書では、Xml変換器としてJackson-Xmlを使用することを説明します.また、jaxbでXml変換を行うこともできます.jaxb方式に変更してください.