잭슨과 열거를 역직렬화하는 중
잭슨 2.5.4와 함께 열거를 해제하려고 하는데, 제 사례가 잘 보이지 않습니다.입력 문자열은 camel case이며, 표준 Enum 규칙에 간단하게 매핑하고 싶습니다.
@JsonFormat(shape = JsonFormat.Shape.STRING)
public enum Status {
READY("ready"),
NOT_READY("notReady"),
NOT_READY_AT_ALL("notReadyAtAll");
private static Map<String, Status> FORMAT_MAP = Stream
.of(Status.values())
.collect(toMap(s -> s.formatted, Function.<Status>identity()));
private final String formatted;
Status(String formatted) {
this.formatted = formatted;
}
@JsonCreator
public Status fromString(String string) {
Status status = FORMAT_MAP.get(string);
if (status == null) {
throw new IllegalArgumentException(string + " has no corresponding value");
}
return status;
}
}
나도 해봤어@JsonValue
다른 곳에서 보고한 선택지였던 게터(getter)에서 헛수고였습니다.모두 다음과 같이 끝납니다.
com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of ...Status from String value 'ready': value not one of declared Enum instance names: ...
내가 뭘 잘못하고 있지?
편집: 잭슨 2.6부터@JsonProperty
serialization/deserialization 값을 지정하기 위해 enum의 각 요소에 대해 지정합니다(여기를 참조).
public enum Status {
@JsonProperty("ready")
READY,
@JsonProperty("notReady")
NOT_READY,
@JsonProperty("notReadyAtAll")
NOT_READY_AT_ALL;
}
(이 답변의 나머지는 이전 버전의 Jackson에서도 유효합니다.)
를 사용해 주세요.@JsonCreator
수신하는 정적 메서드에 주석을 달다String
논쟁.이것이 잭슨이 말하는 팩토리 방식입니다.
public enum Status {
READY("ready"),
NOT_READY("notReady"),
NOT_READY_AT_ALL("notReadyAtAll");
private static Map<String, Status> FORMAT_MAP = Stream
.of(Status.values())
.collect(Collectors.toMap(s -> s.formatted, Function.identity()));
private final String formatted;
Status(String formatted) {
this.formatted = formatted;
}
@JsonCreator // This is the factory method and must be static
public static Status fromString(String string) {
return Optional
.ofNullable(FORMAT_MAP.get(string))
.orElseThrow(() -> new IllegalArgumentException(string));
}
}
테스트는 다음과 같습니다.
ObjectMapper mapper = new ObjectMapper();
Status s1 = mapper.readValue("\"ready\"", Status.class);
Status s2 = mapper.readValue("\"notReadyAtAll\"", Status.class);
System.out.println(s1); // READY
System.out.println(s2); // NOT_READY_AT_ALL
공장방법이 예상하는 바와 같이String
문자열에 유효한 JSON 구문을 사용해야 합니다.이 구문은 따옴표로 묶은 값입니다.
이 방법이 더 빠를 수 있습니다.
public enum Status {
READY("ready"),
NOT_READY("notReady"),
NOT_READY_AT_ALL("notReadyAtAll");
private final String formatted;
Status(String formatted) {
this.formatted = formatted;
}
@Override
public String toString() {
return formatted;
}
}
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.reader(Status.class);
Status status = reader.with(DeserializationFeature.READ_ENUMS_USING_TO_STRING).readValue("\"notReady\"");
System.out.println(status.name()); // NOT_READY
}
@JsonCreator
public static Status forValue(String name)
{
return EnumUtil.getEnumByNameIgnoreCase(Status.class, name);
}
이 정적 메서드를 추가하면 역직렬화 문제가 해결됩니다.
정수 json 속성을 가진 Enum을 검색하는 사용자입니다.다음과 같은 이점이 있습니다.
enum class Status (private val code: Int) {
PAST(0),
LIVE(2),
UPCOMING(1);
companion object {
private val codes = Status.values().associateBy(Status::code)
@JvmStatic @JsonCreator fun from (value: Int) = codes[value]
}
}
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
제게는 해결책이 되었습니다.
https://github.com/FasterXML/jackson-module-kotlin/issues/336#issuecomment-630587525
이 페이지의 솔루션은 단일 필드 및 @JsonFormat(모양 = JsonFormat)에 대해서만 작동합니다.Shape.NATURAL) (기본 형식)
여러 필드와 @JsonFormat(shape = JsonFormat)에 대해 작동합니다.Shape.OBJECT)
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum PinOperationMode {
INPUT("Input", "I"),
OUTPUT("Output", "O")
;
private final String mode;
private final String code;
PinOperationMode(String mode, String code) {
this.mode = mode;
this.code = code;
}
public String getMode() {
return mode;
}
public String getCode() {
return code;
}
@JsonCreator
static PinOperationMode findValue(@JsonProperty("mode") String mode, @JsonProperty("code") String code) {
return Arrays.stream(PinOperationMode.values()).filter(pt -> pt.mode.equals(mode) && pt.code.equals(code)).findFirst().get();
}
}
사용할 수 있습니다.@JsonCreator
주석을 사용하여 문제를 해결합니다.https://www.baeldung.com/jackson-serialize-enums, 를 참조해 주세요.enum 및 serialize-deserialize with Jackson lib 에 대한 설명이 충분히 있습니다.
언급URL : https://stackoverflow.com/questions/31689107/deserializing-an-enum-with-jackson
'programing' 카테고리의 다른 글
각도 지시어에 변수 전달 (0) | 2023.03.23 |
---|---|
바깥쪽 div 크기가 변경되면 스크롤 가능한 div를 바닥에 고정합니다. (0) | 2023.03.23 |
Postgre가 소개한 JSONB 설명SQL (0) | 2023.03.23 |
시도된 가져오기 오류: 'Switch'가 'react-router-dom'에서 내보내지지 않았습니다. (0) | 2023.03.23 |
스프링 부트에서 카페인을 사용하여 캐시별로 다른 사양을 설정할 수 있습니까? (0) | 2023.03.18 |