[英]Spring RequestMapping for controllers that produce and consume JSON
使用多個Spring控制器來使用和生成application/json
,我的代碼充滿了長注釋,如:
@RequestMapping(value = "/foo", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
有沒有辦法生成一個“復合/繼承/聚合”注釋,其中包含consumes
和produces
默認值,這樣我就可以編寫如下內容:
@JSONRequestMapping(value = "/foo", method = RequestMethod.POST)
我們如何定義上面的@JSONRequestMapping
? 注意傳遞的value
和method
就像在@RequestMapping
中一樣,如果默認值不合適,也可以傳入consumes
或produces
。
我需要控制我要回來的東西。 我想produces
/ consumes
注釋的方法,使我獲得相應Content-Type
頭。
從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;
}
您可以在spring的javadoc和github wiki中閱讀有關AliasFor
更多信息。
您的問題的簡單答案是Java中沒有Annotation-Inheritance 。 但是,有一種方法可以以我認為有助於解決問題的方式使用Spring注釋。
類型級別和方法級別都支持@RequestMapping 。
當你在類型級別放置@RequestMapping
,對於該類中的每個方法,大多數屬性都是“繼承的”。 這在Spring參考文檔中提到 。 查看api文檔 ,了解在將@RequestMapping
添加到類型時如何處理每個屬性的詳細信息。 我已經為下面的每個屬性總結了這個:
name
:Type級別的值與方法級別的值連接,使用'#'作為分隔符。 value
:類型級別的值由方法繼承。 path
:類型級別的值由方法繼承。 method
:類型級別的值由方法繼承。 params
:類型級別的值由方法繼承。 headers
:Type級別的值由方法繼承。 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注釋每個請求方法
這種方法的另一個好處是,如果客戶端需要XML而不是JSON,他們就會得到它。 他們只需要在接受標頭中指定xml。
Spring中有2個注釋: @RequestBody和@ResponseBody 。 這些注釋消耗,分別產生JSON。 這里有更多信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.