Spring @RequestBody 和枚举值

新手上路,请多包涵

我有这个 枚举

public enum Reos {

    VALUE1("A"),VALUE2("B");

    private String text;

    Reos(String text){this.text = text;}

    public String getText(){return this.text;}

    public static Reos fromText(String text){
        for(Reos r : Reos.values()){
            if(r.getText().equals(text)){
                return r;
            }
        }
        throw new IllegalArgumentException();
    }
}

还有一个名为 Review 的类,这个类包含一个类型为 enum Reos 的属性。

 public class Review implements Serializable{

    private Integer id;
    private Reos reos;

    public Integer getId() {return id;}

    public void setId(Integer id) {this.id = id;}

    public Reos getReos() {return reos;}

    public void setReos(Reos reos) {
        this.reos = reos;
    }
}

最后,我有一个控制器,它通过 @RequestBody 接收对象审查。

 @RestController
public class ReviewController {

    @RequestMapping(method = RequestMethod.POST, value = "/reviews")
    @ResponseStatus(HttpStatus.CREATED)
    public void saveReview(@RequestBody Review review) {
        reviewRepository.save(review);
    }
}

如果我调用控制器

{"reos":"VALUE1"}

没有问题,但是当我调用时

{"reos":"A"}

我收到这个错误

Could not read document: Can not construct instance of com.microservices.Reos from String value 'A': value not one of declared Enum instance names: [VALUE1, VALUE2] at [Source: java.io.PushbackInputStream@23ce847a; line: 1, column: 40] (through reference chain: com.microservices.Review["reos"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of com.microservices.Reos from String value 'A': value not one of declared Enum instance names: [VALUE1, VALUE2] at [Source: java.io.PushbackInputStream@23ce847a; line: 1, column: 40] (through reference chain: com.microservices.Review["reos"])"

我理解这个问题,但我想知道一种方法来告诉 Spring,对于每个具有 Reos 枚举的对象,使用 Reos.fromText() 而不是 Reos.valueof()。

这可能吗?

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

阅读 1.9k
2 个回答

我找到了我需要的东西。 http://chrisjordan.ca/post/50865405944/custom-json-serialization-for-enums-using-jackson

这是2个步骤。

  1. 覆盖 Reos 枚举的 toString 方法
@Override
public String toString() {
    return text;
}

  1. 用 @JsonCreator 注释 Reos 枚举的 fromText 方法。
 @JsonCreator
public static Reos fromText(String text)

就这样。

我希望这可以帮助其他面临同样问题的人。

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

我个人更喜欢使用 JsonDeserializer 提供的 jackson 编写我自己的反序列化器类。您只需要为您的枚举编写一个反序列化器类。在这个例子中:

 class ReosDeserializer extends JsonDeserializer<Reos> {

    @Override
    public Reos deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {

        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);

        if (node == null) {
            return null;
        }

        String text = node.textValue(); // gives "A" from the request

        if (text == null) {
            return null;
        }

        return Reos.fromText(text);
    }
}

然后,我们应该将上面的类标记为 Reos 的反序列化器类,如下所示:

 @JsonDeserialize(using = ReosDeserializer.class)
public enum Reos {

   // your enum codes here
}

就这样。我们都准备好了。

如果您需要 enum 的序列化程序。您可以通过创建扩展 JsonSerializer 并使用注释 @JsonSerialize 的序列化程序类来以类似的方式做到这一点。

我希望这有帮助。

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

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