web-dev-qa-db-ja.com

Spring Boot Controllerコンテンツネゴシエーション

Spring-bootアプリケーションで記述されたシンプルなRESTコントローラーがありますが、リクエストのContent-Typeパラメーターに基づいてJSONまたはXMLを返すようにコンテンツネゴシエーションを実装する方法がわかりませんheader。誰かが私に何を間違っているのか説明してもらえますか?

コントローラー方式:

@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
  public Message getMessageXML(@RequestParam("text") String text) throws Exception {
    Message message = new Message();
    message.setDate(new Date());
    message.setName("Test");
    message.setAge(99);
    message.setMessage(text);

    return message;
  }

このメソッドを呼び出すときに、常にJSONを取得します(Content-Type することが application/xmlまたはtext/xml)。

それぞれ異なるマッピングと異なるコンテンツタイプを持つ2つのメソッドを実装すると、xmlからXMLを取得できますが、1つのメソッドで2つのmediaTypesを指定すると動作しません(提供された例のように)。

私が望むのは、\messageエンドポイントおよび受信

  • GETリクエストのContent-Typeがapplication/xmlに設定されている場合のXML
  • Content-Typeがapplication/jsonの場合のJSON

どんな助けも大歓迎です。

編集:すべてのメディアタイプを受け入れるようにコントローラーを更新しました

@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }, consumes = MediaType.ALL_VALUE)
  public Message getMessageXML(@RequestParam("text") String text) throws Exception {
    Message message = new Message();
    message.setDate(new Date());
    message.setName("Vladimir");
    message.setAge(35);
    message.setMessage(text);

    return message;
  }
15
Smajl

ヒントはブログ投稿で見つけることができます @ RequestMapping with Produces and Consumes ポイント6.

Content-TypeおよびAcceptヘッダーに関するセクションに注意してください。

生成物と消費物を含む@RequestMapping:ヘッダーのContent-TypeとAcceptを使用して、リクエストの内容と、応答で必要なMIMEメッセージを見つけます。わかりやすくするために、@ RequestMappingは変数を生成および消費します。ここで、メソッドが呼び出される要求コンテンツタイプと応答コンテンツタイプを指定できます。例えば:

@RequestMapping(value="/method6", produces={"application/json","application/xml"}, consumes="text/html")
@ResponseBody
public String method6(){
    return "method6";
}

上記のメソッドは、text/htmlとしてContent-Typeのみを使用してメッセージを消費でき、application/jsonおよびapplication/xmlタイプのメッセージを生成できます。

this 別のアプローチ(ResponseEntityオブジェクトを使用)を試すこともできます。これにより、着信メッセージの種類を見つけて、対応するメッセージを生成できます(@ResponseBodyアノテーションも排除します)

14
abarisone

ContentNegotiationConfigurer を使用できます

まず、構成クラスのconfigureContentNegotiationメソッドをオーバーライドする必要があります。

_@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(false).
            favorParameter(true).
            defaultContentType(MediaType.APPLICATION_JSON).
            mediaType("xml", MediaType.APPLICATION_XML);
    }
}
_

favorParameter(true)-パラメーターよりもパス式の優先を有効にするか、ヘッダーを受け入れます。

defaultContentType(MediaType.APPLICATION_JSON)-デフォルトのコンテンツタイプを設定します。つまり、パス式を渡さない場合、Springは応答としてJSONを生成します。

mediaType("xml", MediaType.APPLICATION_XML)-XMLのパス式キーを設定します。

コントローラを次のように宣言すると:

_@Controller
class AccountController {

    @RequestMapping(value="/accounts", method=RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    public @ResponseBody List<Account> list(Model model, Principal principal) {
        return accountManager.getAccounts(principal) );
    }
}
_

_localhost:8080/app/accounts.json_のように呼び出すと、Springは応答としてJSONを生成します。したがって、_localhost:8080/app/accounts.xml_を呼び出すと、XML応答を受け取ります

これについての詳細情報を見つけることができます こちら

25
Artur Boruński