首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java 8、Spring Boot Starter 2.1.9和Lombok 1.18.10将JSON反序列化到Enum

使用Java 8、Spring Boot Starter 2.1.9和Lombok 1.18.10将JSON反序列化到Enum
EN

Stack Overflow用户
提问于 2020-05-15 03:03:28
回答 3查看 2.5K关注 0票数 1

我试图反序列化为枚举,但JSON值(小写)与枚举常量(大写)不同。

这是枚举:

代码语言:javascript
复制
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum ContractTypes {

  @JsonProperty("product")
  PRODUCT("product"), 
  @JsonProperty("service")
  SERVICE("service");

  private String value;
}

如您所见,我已经使用@JsonProperty注释对元素进行了注释,以尝试将提供的值映射到合适的常量。

我还尝试用@JsonValue注释来注释属性value。在这两种情况下,我都得到了相同的结果:

代码语言:javascript
复制
Field error in object 'createContractRequestDto' on field 'contractType': rejected value [product]; codes [typeMismatch.createContractRequestDto.contractType,typeMismatch.contractType,typeMismatch.enm.ContractTypes,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [createContractRequestDto.contractType,contractType]; arguments []; default message [contractType]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'enm.ContractTypes' for property 'contractType'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [enm.ContractTypes] for value 'product'; nested exception is java.lang.IllegalArgumentException: No enum constant enm.ContractTypes.product]]

为什么@JsonProperty@JsonValue注解不起作用?我必须如何编写解决方案才能将JSON值映射到合适的枚举元素?

EN

回答 3

Stack Overflow用户

发布于 2020-05-15 03:24:59

我们也可以创建一个自定义的转换器。

代码语言:javascript
复制
public class ContractTypesConverter implements Converter<String, ContractTypes> {

   @Override
   public ContractTypes convert(String source) {
     return ContractTypes.valueOf(source.toUpperCase());
   }
}

这可以进一步写成这样(感谢lambda)

代码语言:javascript
复制
Converter<String, ContractTypes> converter = source -> ContractTypes.valueOf(source.toUpperCase());

并将其注册到WebMvcConfigurer,如下所示

代码语言:javascript
复制
@Configuration
public class WebConfiguration implements WebMvcConfigurer {

   // ... other configurations

   @Override
   public void addFormatters(FormatterRegistry registry) {
      registry.addConverter(new ContractTypesConverter());
   }

}
票数 2
EN

Stack Overflow用户

发布于 2020-05-15 05:48:37

这对我很有效。不确定您在代码中遗漏了什么。

代码语言:javascript
复制
@Getter
public enum ContractTypes {

    PRODUCT("product"),
    SERVICE("service");

    private String value;

    ContractTypes(String value){
        this.value = value;
    }

    @JsonValue
    public String getValue() {
        return value;
    }
}

@NoArgsConstructor
@Setter
@Getter
static class Holder {
    private ContractTypes contractTypes;
}

@Test
public void test() throws IOException {
    Holder holder = new ObjectMapper().readValue("{\"contractTypes\":\"product\"}", Holder.class);
    assertEquals(ContractTypes.PRODUCT, holder.contractTypes);
}
票数 2
EN

Stack Overflow用户

发布于 2020-05-15 03:14:14

这些注释作用于属性,而不是枚举类型。您可以使用like PRODUCT直接使用枚举,或者编写一个自定义的反序列化程序,并将其用于在属性上进行反序列化注释。

代码语言:javascript
复制
@JsonDeserialize(using = ContractTypesDeserializer.class)
ContractTypes contractTypes;

客户反序列化程序实现

代码语言:javascript
复制
public class ContractTypesDeserializer extends StdDeserializer<ContractTypes> {
  private static final long serialVersionUID = -4714891596189L;

  public ContractTypesDeserializer() {
    super ContractTypes.class);
  }

  protected ContractTypesDeserializer(Class ContractTypes> type) {super(type);}

  @Override
  public ContractTypes deserialize(JsonParser parser, DeserializationContext context)
      throws IOException, JsonProcessingException {
      return ContractTypes.valueOf(parser.getText().toUpperCase());
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61805414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档