Jackson @ResponseBody定制序列化Spring @Controller per方法

时间:2017-08-23 03:57:35

标签: java spring-mvc jackson

我有一个Java Enum:

public enum MyEnum {
    FOO("fee", "The fee foo", "lorem ipsum"),
    BAR("bee", "The bar bee", "ipsum lorem"),
    BAZ("boo", "The baz boo", "blah blah");

    private final String id;
    private final String summary;
    private final String description;

    @JsonValue
    public String getId() {
        return id;
    }
}

@JsonValue是故意的,因为我希望在大多数JSON序列化中默认返回id作为“值”(例如"fee"),但对于我的其他控制器,我想序列化具有所有属性的枚举:

@Controller
public class MyEnumController {
    @RequestMapping(method = RequestMethod.GET, value = "/my-enum-types", produces = {APPLICATION_JSON_UTF8_VALUE})
    @ResponseStatus(HttpStatus.OK)
    public @ResponseBody ResponseEntity<MyEnum[]> getMyEnumTypes() {
        return ResponseEntity.ok(MyEnum.values());
    }

    /*
        desired output: "[
            {
                "id": "fee",
                "summary: "The fee foo",
                "description": "lorem ipsum"
            }, 
            ...
        ]"

        actual output: "[
            "fee",
            "bee",
            "boo"
        ]"
    */
}

我试图使用@JsonFormat(shape = JsonFormat.Shape.OBJECT)注释枚举类,但似乎@JsonValue注释会覆盖此配置。从类中删除@JsonValue会修复此问题,但如果我这样做,则包含MyEnum属性的每个其他类都需要@JsonFormat(shape = JsonFormat.Shape.String)来获取实际的枚举名称,或@JsonSerialize(using = MyEnumToIdPropertySerialzer.class)来获取原始@JsonValue行为(据我所知)。

我也知道可以使用REST方式的对象的自定义表示来配置媒体类型(例如application/vnd.com.example.full_enum+json),但这似乎只涉及偶尔会发生的事情。我愿意接受,如果这是最合适的方法,但我也希望简单地用@WithCustomSerializer(using = MyEnumSerializer.class, for = MyEnum.class)之类的方法注释控制器方法可以避免这些配置问题。

是否有一种注释习惯的方式来声明@Controller方法包含每个方法的自定义序列化而不是默认的(@JsonValue)类注释行为?

UPDATE:

我想我需要在上一个答案之后澄清我不希望我的控制器返回一个字符串列表。我希望将其签名保留为MyEnum的数组,因为它应该是它。

该类上的任何注释都将影响全局的JSON序列化,并且我希望将其全局表示保持为我已经对该类进行注释的方式。

1 个答案:

答案 0 :(得分:-1)

请尝试以下代码:

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {

    FOO("fee", "The fee foo", "lorem ipsum"),
    BAR("bee", "The bar bee", "ipsum lorem"),
    BAZ("boo", "The baz boo", "blah blah");

    @JsonProperty
    private final String id;
    @JsonProperty
    private final String summary;
    @JsonProperty
    private final String description;

    private MyEnum(String id, String summary, String description) {
        this.id=id;
        this.summary=summary;
        this.description=description;
    }
}