当前位置: 首页 > 知识库问答 >
问题:

Spring@Request estBody和枚举值

洪俊能
2023-03-14

我有这个数字

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的类,该类包含枚举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 enum的对象,都使用Reos。fromText()而不是Reos。valueof()。

这可能吗?

共有3个答案

祁雪峰
2023-03-14

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

您可以扩展AbstractHttpMessageConverter

施洛城
2023-03-14

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

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的序列化器类并使用注释@JsonSerializer以类似的方式做到这一点。

我希望这有帮助。

何涵衍
2023-03-14

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

这是2步。

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

这就是全部。

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

 类似资料:
  • 问题内容: 当我使用DataContractJsonSerializer序列化枚举值时,它将序列化枚举的数值,而不是字符串名称。 IE浏览器: 序列化foo.bar的值将返回“ 0”,而不是“ bar”。 我更喜欢它,是否有一种方法可以覆盖它? 编辑: 因为我不想更改序列化程序,所以我使用了一个简单的变通办法。 我在类中公开了要序列化的属性,该属性在值上调用ToString,即: 问题答案: 看起

  • 问题内容: 我知道PHP没有本地枚举。但是我已经习惯了Java世界中的他们。我很乐意使用枚举来提供IDE的自动完成功能可以理解的预定义值。 常量可以解决问题,但是存在名称空间冲突问题,并且(或者实际上是 因为 )它们是全局的。数组没有名称空间问题,但是它们太含糊,可以在运行时覆盖它们,而IDE很少(从不?)不知道如何自动填充键。 您通常使用任何解决方案/解决方法吗?有谁回想起PHP家伙是否对枚举有

  • 问题内容: Enumeration <有区别吗?扩展ZipEntry>和Enumeration ?如果是这样,有什么区别? 问题答案: 拥有其中一种后,您在做什么上没有实际差异,因为type参数仅在“输出”位置使用。另一方面,在您可以 用作 其中一个的方面有很大的不同。 假设您有一个-您无法将其传递给作为其参数之一的方法。您 可以 将其传递给采用方法。 当您有一个在输入和输出位置都使用type参数

  • 问题内容: 枚举具有获取枚举常量的方法,并且在具有 我发现的名称的类中存在的相同类型的方法都给出相同的输出。那还有什么其他区别。如果没有区别,那么为什么要添加JSL ? 问题答案: 包括该方法的原因是它可以与任何方法一起使用。相比之下, 用于特定方法的方法仅适用于该特定方法…,因为类不能被多态使用。 显然,该方法仅在您实现 需要 针对多种类型使用的代码的情况下才真正有用……而泛型则不会削减它。

  • 问题内容: 我们有一个带有枚举字段-的实体,我们想使用JPA注释-为它设置默认值。 但是,当我们将实体保存到数据库时,此字段的值为和。对于布尔字段- 正确的默认值()已保存。 如果改为使用:,则会在保存时得到以下异常: 我们做错了什么?为什么它仅适用于布尔值? 问题答案: 当某些SQL代码在未为emailCommunicationStatus列指定任何值的情况下插入一行时,您所做的工作很有用。在这

  • 在使用Spring MVC的REST api中,如果我想将可以作为超文本传输协议GET请求参数传递的字符串值限制为以下参数之一 价值A价值B 我认为我应该在java中使用枚举类型。 然而,这只处理Enum的序列化。当我在Spring控制器中接收作为请求Param时,会出现,因为 我已经阅读了下面的文章https://www.baeldung.com/spring-enum-request-para