У меня есть ситуация, когда я получаю логическое значение в виде строки «0» или «1» из внешнего источника. При отображении Джексон не принимает это и выдает следующую ошибку:
InvalidFormatException: Невозможно десериализовать значение типа boolean
из строки «1»
Таким образом, я делает следующую пользовательскую десериализацию, которая работает.
Рабочий пример, когда выполняется без компоновщика
@Getter
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
private boolean bool;
// many other fields
}
class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return "1".equals(parser.getText());
}
}
Но мне нужно это для работы со сборщиком и записи его следующим образом. Это больше не работает. Выдает ту же ошибку, что и выше. Есть ли способ обойти это для строителя, чтобы работать с пользовательской десериализацией? Обратите внимание, что я бы хотел использовать Lombok's Builder, если это вообще невозможно. Спасибо.
Неудовлетворительный пример, когда долой строителя. (что я хотел бы исправить, чтобы заставить его работать)
@Getter
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
private boolean bool;
// many other fields
}
class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return "1".equals(parser.getText());
}
}
Быстрый тестовый пример, чтобы проверить это, если хотите.
public class ATest {
@Test
public void myTest() throws IOException {
ObjectMapper mapper = new ObjectMapper();
// test passes if MyClass doesn't use builder.
MyClass myClass = mapper.readValue("{\"bool\":\"1\"}", MyClass.class);
assertTrue(myClass.isBool());
}
}
РЕДАКТИРОВАТЬ: Попытка предложенных вариантов в соответствии с ответом ниже
Вариант 1:
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
private boolean bool;
// many other fields
@JsonSetter
private void setBool(String value){
this.bool = "1".equals(value);
}
}
class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return !"0".equals(parser.getText());
}
}
Получение следующей ошибки:
com.faster xml .jackson.databind.JsonMappingException: проблема десериализации свойства 'bool' (ожидаемый тип: [простой тип, класс java .lang.String]; фактический тип: java.lang.Boolean
), проблема: несоответствие типа аргумента at [Source: (String) "{" bool ":" 1 "}"; строка: 1, столбец: 9] (через цепочку ссылок: aaaMyClass ["bool"])
Опция 2:
@Getter
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
private boolean bool;
}
Получение следующей ошибки:
com.faster xml .jackson.databind.ex c .InvalidFormatException: Невозможно десериализовать значение типа boolean
из строки "1": только "true" или "false" распознаются в [Source: ( Строка) "{" BOOL ":" 1 "}"; строка: 1, столбец: 9] (через цепочку ссылок: aaaMyClass $ MyClassBuilder ["bool"])