用于生成和使用 JSON 的控制器的 Spring RequestMapping

新手上路,请多包涵

使用多个消费和生产 application/json 的 Spring 控制器,我的代码充满了长注释,例如:

     @RequestMapping(value = "/foo", method = RequestMethod.POST,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)

有没有办法使用 consumesproduces默认 值生成“复合/继承/聚合”注释,这样我就可以改写如下内容:

     @JSONRequestMapping(value = "/foo", method = RequestMethod.POST)

我们如何定义类似 @JSONRequestMapping 的东西? Notice the value and method passed in just like in @RequestMapping , also good to be able to pass in consumes or produces 如果默认值不合适。

我需要控制我要返回的内容。我想要 produces / consumes 注释方法,以便获得适当的 Content-Type 标头。

原文由 Roshan Mathews 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 656
2 个回答

从 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 的 javadocgithub wiki 中阅读更多关于 AliasFor 的信息。

原文由 Ali Dehghani 发布,翻译遵循 CC BY-SA 3.0 许可协议

您的问题的简单答案是 Java 中没有 Annotation-Inheritance 。但是,有一种方法可以以我认为有助于解决您的问题的方式使用 Spring 注释。

@RequestMapping 在类型级别和方法级别均受支持。

当您将 @RequestMapping 放在类型级别时,该类中的每个方法的大多数属性都是“继承的”。 Spring 参考文档 中提到 了这一点。查看 api 文档,了解在将 @RequestMapping 添加到类型时如何处理每个属性的详细信息。我针对以下每个属性总结了这一点:

  • 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;
    }
}

原文由 FGreg 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题