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

时间:2016-02-01 05:56:25

标签: java json spring spring-mvc

使用多个使用和生成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之类的内容?请注意valuemethod就像@RequestMapping一样传入,如果默认值不是consumesproduces,也可以通过producesconsumes。适合。

我需要控制我回来的东西。我想要Content-Type / let asset = AVAsset(url: URL(fileURLWithPath: "asset/p2a2.aif")) let track = asset.tracks[0] let desc = track.formatDescriptions[0] as! CMAudioFormatDescription let basic = CMAudioFormatDescriptionGetStreamBasicDescription(desc) print(basic?.pointee.mSampleRate) 注释方法,以便获得相应的print(track.naturalTimeScale) 标题。

5 个答案:

答案 0 :(得分:50)

从Spring 4.2.x开始,您可以使用@RequestMapping作为元注释创建自定义映射注释。所以:

  

有没有办法生成"复合/继承/聚合"   具有消耗和产生的默认值的注释,例如I   可以写一些像:

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

您可以在春季javadocgithub wiki了解有关AliasFor的更多信息。

答案 1 :(得分:18)

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

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

当您将@RequestMapping放在类型级别时,对于该类中的每个方法,大多数属性都是“继承的”。这是Spring参考文档中的mentioned。有关在向类型添加@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;
    }
}

答案 2 :(得分:8)

您可以使用@RestController代替@Controller注释。

答案 3 :(得分:5)

您根本不需要配置消耗或生成属性。 Spring将根据以下因素自动提供JSON。

  • 请求的接受标头是 application / json
  • @ResponseBody 带注释的方法
  • 杰克逊图书馆的课程

您还应该遵循Wim的建议,并使用 @RestController 注释定义您的控制器。这样可以避免使用 @ResponseBody

为每个请求方法添加注释

这种方法的另一个好处是,如果客户端需要XML而不是JSON,他们就会得到它。他们只需要在接受标头中指定xml。

答案 4 :(得分:0)

Spring中有2个注释: @RequestBody @ResponseBody 。这些注释消耗,分别产生JSON。更多信息here