application/json
を消費および生成する複数のSpringコントローラーを使用すると、私のコードには次のような長い注釈が散らばっています。
@RequestMapping(value = "/foo", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
defaultconsumes
およびproduces
の値を持つ「合成/継承/集計」アノテーションを作成する方法はありますか。
@JSONRequestMapping(value = "/foo", method = RequestMethod.POST)
上記の@JSONRequestMapping
のようなものをどのように定義しますか? value
とmethod
が@RequestMapping
と同じように渡されることに注意してください。デフォルトが適切でない場合は、consumes
またはproduces
を渡すこともできます。
返すものを制御する必要があります。適切なContent-Type
ヘッダーを取得するために、produces
/consumes
アノテーションメソッドが必要です。
Spring 4.2.xでは、@RequestMapping
をメタ注釈として使用して、カスタムマッピング注釈を作成できます。そう:
消費と生成のデフォルト値を使用して「合成/継承/集約」注釈を作成する方法はありますか?
@JSONRequestMapping(value = "/foo", method = RequestMethod.POST)
はい、そのような方法があります。次のようなメタ注釈を作成できます。
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@RequestMapping(consumes = "application/json", produces = "application/json")
public @interface JsonRequestMapping {
@AliasFor(annotation = RequestMapping.class, attribute = "value")
String[] value() default {};
@AliasFor(annotation = RequestMapping.class, attribute = "method")
RequestMethod[] method() default {};
@AliasFor(annotation = RequestMapping.class, attribute = "params")
String[] params() default {};
@AliasFor(annotation = RequestMapping.class, attribute = "headers")
String[] headers() default {};
@AliasFor(annotation = RequestMapping.class, attribute = "consumes")
String[] consumes() default {};
@AliasFor(annotation = RequestMapping.class, attribute = "produces")
String[] produces() default {};
}
次に、デフォルト設定を使用するか、必要に応じてそれらを上書きすることもできます。
@JsonRequestMapping(method = POST)
public String defaultSettings() {
return "Default settings";
}
@JsonRequestMapping(value = "/override", method = PUT, produces = "text/plain")
public String overrideSome(@RequestBody String json) {
return json;
}
AliasFor
の詳細については、春の javadoc および github wiki をご覧ください。
あなたの質問に対する簡単な答えは、 Javaのアノテーション-継承 がないということです。ただし、問題の解決に役立つと思う方法でSpringアノテーションを使用する方法があります。
@ RequestMapping は、タイプレベルとメソッドレベルの両方でサポートされています。
@RequestMapping
を型レベルに配置すると、そのクラスの各メソッドのほとんどの属性が「継承」されます。これは、Springリファレンスドキュメントの 言及 です。タイプに@RequestMapping
を追加するときの各属性の処理方法の詳細については、 api docs をご覧ください。以下に、各属性についてこれをまとめました。
name
:タイプレベルの値は、 '#'をセパレータとして使用してメソッドレベルの値と連結されます。value
:タイプレベルの値はメソッドによって継承されます。path
:タイプレベルの値はメソッドによって継承されます。method
:タイプレベルの値はメソッドによって継承されます。params
:タイプレベルの値はメソッドによって継承されます。headers
:タイプレベルの値はメソッドによって継承されます。consumes
:タイプレベルの値はメソッドによってオーバーライドされます。produces
:タイプレベルの値はメソッドによってオーバーライドされます。これを使用する方法を示す簡単なコントローラーの例を次に示します。
package com.example;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(path = "/",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE,
method = {RequestMethod.GET, RequestMethod.POST})
public class JsonProducingEndpoint {
private FooService fooService;
@RequestMapping(path = "/foo", method = RequestMethod.POST)
public String postAFoo(@RequestBody ThisIsAFoo theFoo) {
fooService.saveTheFoo(theFoo);
return "http://myservice.com/foo/1";
}
@RequestMapping(path = "/foo/{id}", method = RequestMethod.GET)
public ThisIsAFoo getAFoo(@PathVariable String id) {
ThisIsAFoo foo = fooService.getAFoo(id);
return foo;
}
@RequestMapping(path = "/foo/{id}", produces = MediaType.APPLICATION_XML_VALUE, method = RequestMethod.GET)
public ThisIsAFooXML getAFooXml(@PathVariable String id) {
ThisIsAFooXML foo = fooService.getAFoo(id);
return foo;
}
}
@RestController
アノテーションの代わりに@Controller
を使用できます。
消費または生成属性を設定する必要はまったくありません。 Springは、次の要因に基づいてJSONを自動的に提供します。
また、Wimの提案に従い、コントローラーを@ RestControllerアノテーションで定義する必要があります。これにより、各リクエストメソッドに@ ResponseBodyで注釈を付ける必要がなくなります。
このアプローチのもう1つの利点は、クライアントがJSONではなくXMLを必要とする場合、それを取得することです。 Acceptsヘッダーでxmlを指定するだけです。
Springには2つの注釈があります:@ RequestBodyと@ ResponseBodyこれらの注釈は、それぞれJSONを生成します。詳細情報 こちら 。