Java Spring @RequestBody 和 Enum 值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33637427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring @RequestBody and Enum value
提问by reos
I Have this 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();
}
}
And a class called Review, this class contains a property of the type enum Reos.
还有一个名为 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;
}
}
Finally I have a controller that receives an object review with the @RequestBody.
最后,我有一个控制器,它通过@RequestBody接收对象。
@RestController
public class ReviewController {
@RequestMapping(method = RequestMethod.POST, value = "/reviews")
@ResponseStatus(HttpStatus.CREATED)
public void saveReview(@RequestBody Review review) {
reviewRepository.save(review);
}
}
If I invoke the controller with
如果我调用控制器
{"reos":"VALUE1"}
There is not problem, but when I invoke with
没有问题,但是当我调用时
{"reos":"A"}
I get this error
我收到这个错误
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.Hymanson.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"])"
I undertand the problem, but I wanted to know a way to tell Spring that for every object with Reos enum use Reos.fromText() instead of Reos.valueof().
我理解这个问题,但我想知道一种方法来告诉 Spring 对于每个带有 Reos 枚举的对象使用 Reos.fromText() 而不是 Reos.valueof()。
Is this possible?
这可能吗?
采纳答案by reos
I've found what I need.
我找到了我需要的东西。
http://chrisjordan.ca/post/50865405944/custom-json-serialization-for-enums-using-Hymanson
http://chrisjordan.ca/post/50865405944/custom-json-serialization-for-enums-using-Hymanson
It was 2 steps.
这是2个步骤。
Override the toString method of the Reos enum
@Override public String toString() { return text; }
Annotate with @JsonCreator the fromText method of the Reos enum.
@JsonCreator public static Reos fromText(String text)
覆盖 Reos 枚举的 toString 方法
@Override public String toString() { 返回文本;}
使用 @JsonCreator 注释 Reos 枚举的 fromText 方法。
@JsonCreator 公共静态 Reos fromText(String text)
And that's all.
就这样。
I hope this could help others facing the same problem.
我希望这可以帮助其他面临同样问题的人。
回答by Chris Thompson
You need to use a custom MessageConverter
that calls your custom fromText()
method. There's an article herethat outlines how to do it.
您需要使用MessageConverter
调用您的自定义fromText()
方法的自定义。有一篇文章在这里,概述了如何做到这一点。
You extend AbstractHttpMessageConverter<Reos>
and implement the required methods, and then you register it.
您扩展AbstractHttpMessageConverter<Reos>
并实现所需的方法,然后注册它。
回答by Manoj Shrestha
I personally prefer writing my own deserializer class using JsonDeserializer
provided by Hymanson
. You just need to write a deserializer class for your enum. In this example:
我个人比较喜欢写我自己的解串器类使用JsonDeserializer
提供Hymanson
。您只需要为您的枚举编写一个反序列化器类。在这个例子中:
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);
}
}
Then, we should mark the above class as a deserializer class of Reos as follows:
然后,我们应该将上述类标记为 Reos 的反序列化器类,如下所示:
@JsonDeserialize(using = ReosDeserializer.class)
public enum Reos {
// your enum codes here
}
That's all. We're all set.
就这样。我们都准备好了。
In case if you need the serializer for the enum
. You can do that in the similar way by creating a serializer class extending JsonSerializer
and using the annotation @JsonSerialize
.
如果您需要enum
. 您可以通过创建扩展JsonSerializer
和使用注释的序列化程序类以类似的方式做到这一点@JsonSerialize
。
I hope this helps.
我希望这有帮助。