我使用JAVA 1.6和Jackson 1.9.9,我有一个enum

public enum Event {
    FORGOT_PASSWORD("forgot password");

    private final String value;

    private Event(final String description) {
        this.value = description;
    }

    @JsonValue
    final String value() {
        return this.value;
    }
}

我已经添加了一个@JsonValue,这似乎做的工作,它序列化对象:

{"event":"forgot password"}

但当我尝试反序列化时,我得到

Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.globalrelay.gas.appsjson.authportal.Event from String value 'forgot password': value not one of declared Enum instance names

我错过了什么?


当前回答

我是这样做的:

// Your JSON
{"event":"forgot password"}

// Your class to map 
public class LoggingDto {
    @JsonProperty(value = "event")
    private FooEnum logType;
}

//Your enum
public enum FooEnum {

    DATA_LOG ("Dummy 1"),
    DATA2_LOG ("Dummy 2"),
    DATA3_LOG ("forgot password"),
    DATA4_LOG ("Dummy 4"),
    DATA5_LOG ("Dummy 5"),
    UNKNOWN ("");

    private String fullName;

    FooEnum(String fullName) {
        this.fullName = fullName;
    }

    public String getFullName() {
        return fullName;
    }

    @JsonCreator
    public static FooEnum getLogTypeFromFullName(String fullName) {
        for (FooEnum logType : FooEnum.values()) {
            if (logType.fullName.equals(fullName)) {
                return logType;
            }
        }
        return UNKNOWN;
    }


}

因此,类LoggingDto的属性“logType”的值将是DATA3_LOG

其他回答

试试这个。

public enum Event {

    FORGOT_PASSWORD("forgot password");

    private final String value;

    private Event(final String description) {
        this.value = description;
    }

    private Event() {
        this.value = this.name();
    }

    @JsonValue
    final String value() {
        return this.value;
    }
}

可以采用多种方法将JSON对象反序列化为枚举。我最喜欢的风格是创建一个内部类:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;

import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.fasterxml.jackson.annotation.JsonFormat.Shape.OBJECT;

@JsonFormat(shape = OBJECT)
public enum FinancialAccountSubAccountType {
  MAIN("Main"),
  MAIN_DISCOUNT("Main Discount");

  private final static Map<String, FinancialAccountSubAccountType> ENUM_NAME_MAP;
  static {
    ENUM_NAME_MAP = Arrays.stream(FinancialAccountSubAccountType.values())
      .collect(Collectors.toMap(
        Enum::name,
        Function.identity()));
  }

  private final String displayName;

  FinancialAccountSubAccountType(String displayName) {
    this.displayName = displayName;
  }

  @JsonCreator
  public static FinancialAccountSubAccountType fromJson(Request request) {
    return ENUM_NAME_MAP.get(request.getCode());
  }

  @JsonProperty("name")
  public String getDisplayName() {
    return displayName;
  }

  private static class Request {
    @NotEmpty(message = "Financial account sub-account type code is required")
    private final String code;
    private final String displayName;

    @JsonCreator
    private Request(@JsonProperty("code") String code,
                    @JsonProperty("name") String displayName) {
      this.code = code;
      this.displayName = displayName;
    }

    public String getCode() {
      return code;
    }

    @JsonProperty("name")
    public String getDisplayName() {
      return displayName;
    }
  }
}

我发现最简单的方法是使用@JsonFormat.Shape。枚举的OBJECT注释。

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum{
    ....
}

这里,'value'充当反序列化器,'namespace'充当序列化器。因此,你可以在保存时将值“Student Absent”传递给API,在DB中它将被保存为“STUDENT_ABSENT”。另一方面,在检索类中的数据时,API将返回“Student Absent”。

import com.fasterxml.jackson.annotation.JsonProperty;
public enum AttendanceEnums {
    STUDENT_PRESENT,
    @JsonProperty(value = "Student Absent", namespace = "Student Absent")
    STUDENT_ABSENT;
}

我是这样做的:

// Your JSON
{"event":"forgot password"}

// Your class to map 
public class LoggingDto {
    @JsonProperty(value = "event")
    private FooEnum logType;
}

//Your enum
public enum FooEnum {

    DATA_LOG ("Dummy 1"),
    DATA2_LOG ("Dummy 2"),
    DATA3_LOG ("forgot password"),
    DATA4_LOG ("Dummy 4"),
    DATA5_LOG ("Dummy 5"),
    UNKNOWN ("");

    private String fullName;

    FooEnum(String fullName) {
        this.fullName = fullName;
    }

    public String getFullName() {
        return fullName;
    }

    @JsonCreator
    public static FooEnum getLogTypeFromFullName(String fullName) {
        for (FooEnum logType : FooEnum.values()) {
            if (logType.fullName.equals(fullName)) {
                return logType;
            }
        }
        return UNKNOWN;
    }


}

因此,类LoggingDto的属性“logType”的值将是DATA3_LOG