Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java 8、Spring Boot Starter 2.1.9和Lombok 1.18.10将JSON反序列化为Enum_Java_Json_Enums_Jackson_Jackson Databind - Fatal编程技术网

使用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,java,json,enums,jackson,jackson-databind,Java,Json,Enums,Jackson,Jackson Databind,我试图反序列化到枚举,但JSON值(小写)与枚举常量(大写)不同 这是枚举: import com.fasterxml.jackson.annotation.JsonProperty; 导入lombok.allargsconstuctor; 进口龙目吸气剂; @吸气剂 @AllArgsConstructor 公共枚举类型{ @JsonProperty(“产品”) 产品(“产品”), @JsonProperty(“服务”) 服务(“服务”); 私有字符串值; } 如您所见,我用@JsonProp

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

这是枚举:

import com.fasterxml.jackson.annotation.JsonProperty;
导入lombok.allargsconstuctor;
进口龙目吸气剂;
@吸气剂
@AllArgsConstructor
公共枚举类型{
@JsonProperty(“产品”)
产品(“产品”),
@JsonProperty(“服务”)
服务(“服务”);
私有字符串值;
}
如您所见,我用
@JsonProperty
注释对元素进行了注释,以尝试将提供的值映射到合适的常量

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

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值映射到合适的枚举元素?

这些注释适用于属性,而不是枚举类型。 您可以直接使用enum,比如
PRODUCT
,或者编写一个自定义反序列化程序,并使用它对属性进行反序列化注释

@JsonDeserialize(using = ContractTypesDeserializer.class)
ContractTypes contractTypes;
客户反序列化器实现

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());
  }
}
public类ContractTypesDeserializer扩展StdDeserializer{
私有静态最终长serialVersionUID=-4714891596189L;
公共合同类型序列化程序(){
超级合同类型(类);
}
受保护的ContractTypesSerializer(类ContractTypes>type){super(type);}
@凌驾
PublicContractTypes反序列化(JsonParser解析器,反序列化上下文)
抛出IOException、JsonProcessingException{
返回ContractTypes.valueOf(parser.getText().toUpperCase());
}
}

我们还可以创建自定义转换器

public class ContractTypesConverter implements Converter<String, ContractTypes> {

   @Override
   public ContractTypes convert(String source) {
     return ContractTypes.valueOf(source.toUpperCase());
   }
}
然后像这样在
webmvcconfiguer
中注册它

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

   // ... other configurations

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

}

这对我有用。不确定代码中遗漏了什么

@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);
}

你尝试过这个解决方案吗?
@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);
}