Spring @RequestBody和Enum值

我有这个枚举

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()。

这可能吗?

我找到了我需要的东西。

http://chrisjordan.ca/post/50865405944/custom-json-serialization-for-enums-using-jackson

这是两个步骤。

  1. 重写Reos枚举的toString方法

    @Override public String toString(){return text; }

  2. 使用@JsonCreator注释Reos枚举的fromText方法。

    @JsonCreator public static Reos fromText(String text)

就这样。

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

您需要使用调用自定义fromText()方法的自定义MessageConverter 。 这里有一篇文章概述了如何做到这一点。

您扩展AbstractHttpMessageConverter并实现所需的方法,然后注册它。

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

 class ReosDeserializer extends JsonDeserializer { @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的序列化程序类以类似的方式执行此@JsonSerialize

我希望这有帮助。