简体   繁体   English

每个方法在Spring @Controller上的Jackson @ResponseBody自定义序列化

[英]Jackson @ResponseBody custom serialization on Spring @Controller per method

I Have a Java Enum: 我有一个Java枚举:

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

the @JsonValue is intentional as I want the id to be returned as the "value" by default in most JSON serializations (eg "fee" ), however for my rest controller, I would like to Serialize the enum with all its properties: @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"
        ]"
    */
}

I have attempted to annotate the enum class with @JsonFormat(shape = JsonFormat.Shape.OBJECT) however it seems as though the @JsonValue annotation overrides this configuration. 我试图用@JsonFormat(shape = JsonFormat.Shape.OBJECT)注释枚举类,但是似乎@JsonValue注释覆盖了此配置。 removing @JsonValue from the class fixes this, but if I did that, every other class containing a MyEnum attribute would need to have @JsonFormat(shape = JsonFormat.Shape.String) to get the actual enum name or @JsonSerialize(using = MyEnumToIdPropertySerialzer.class) to get the original @JsonValue behaviour (as far as I am aware). 从类中删除@JsonValue可以解决此问题,但如果我这样做,则每个其他包含MyEnum属性的类都需要具有@JsonFormat(shape = JsonFormat.Shape.String)才能获取实际的枚举名称或@JsonSerialize(using = MyEnumToIdPropertySerialzer.class)以获取原始的@JsonValue行为(据我所知)。

I'm also aware of media types being configurable with custom representations of an object in a REST fashion (eg application/vnd.com.example.full_enum+json ), but this seems quite involved for something that will only happen occasionally. 我还知道可以使用REST方式(例如application/vnd.com.example.full_enum+json )用对象的自定义表示来配置媒体类型,但这似乎只涉及偶尔发生的事情。 I'm willing to accept if this is the most appropriate approach but I would also have hoped that simply annotating the controller method with something like @WithCustomSerializer(using = MyEnumSerializer.class, for = MyEnum.class) would save me from these configuration woes. 我愿意接受这是否是最合适的方法,但我也希望仅@WithCustomSerializer(using = MyEnumSerializer.class, for = MyEnum.class)注释控制器方法将使我免于这些配置@WithCustomSerializer(using = MyEnumSerializer.class, for = MyEnum.class)

Is there an annotation-idiomatic way of declaring a @Controller method to include custom serialization per method instead of its default ( @JsonValue ) class annotated behaviour? 是否有一种声明惯用的方式来声明@Controller方法以包括每个方法的自定义序列化,而不是其默认的( @JsonValue )类注释行为?

UPDATE: 更新:

I think I need to clarify after the previous answer that I don't want my controller to be returning a list of strings. 我想我需要在上一个答案之后澄清一下,我不希望我的控制器返回字符串列表。 I would like to have its signature remain as an Array of MyEnum s as that is what it should be. 我希望将其签名保留为MyEnum的Array,因为它应该是这样。

Any annotations on the class will effect the JSON serialization globally and I would like to keep its global representation the way I've annotated the class already. 该类上的任何注释都将在全局范围内影响JSON序列化,我希望保持其全局表示的方式与我对类的注释方式相同。

Please try below code: 请尝试以下代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM