Как разобрать поле, которое может быть строкой и может быть массивом с Джексоном - PullRequest
2 голосов
/ 19 мая 2019

Я новичок в Java и ObjectMapper.Я пытаюсь проанализировать поле json, возможно, ключ имеет два типа, это может быть строка или массив.

примеры:

{
  "addresses": [],
  "full_name": [
    "test name_1",
    "test name_2"
  ],
}

или

{
{
  "addresses": [],
  "full_name": "test name_3",
}
}

Пример класса:


@JsonIgnoreProperties(ignoreUnknown = true)
@Data -> lombok.Data
public class Document {

    private List<String> addresses;

    @JsonProperty("full_name")
    private String fullName;
}

Я использовал objectMapper для десериализации json, работает правильно, когда в поле 'full_name' есть строка, но когда приходит массив, десериализация не удалась.

Идея состоит в том,что, когда приходит строка, в атрибуте помещается значение, а при поступлении массива объединяются элементы массива в виде строки (String.join (",", value))

Возможно ли применить пользовательскую десериализацию в методе класса?Например, setFullName () (используйте lombok.Data)

Я видел другие примеры на этом сайте, но не работает.

Спасибо за все

Ответы [ 3 ]

5 голосов
/ 19 мая 2019

Из Джексона 2.6 вы можете использовать JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY

@JsonProperty("full_name")
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private String[] fullName;
2 голосов
/ 19 мая 2019

Разрабатывая ответ @Deadpool, вы можете использовать setter, который принимает массив и затем присоединяет его к строке:

@JsonProperty("full_name")
@JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
void setFullName(String[] name)
{
    this.fullName = String.join(",", name);
}
0 голосов
/ 19 мая 2019

Оба ответа великолепны. Я просто хочу упомянуть о кастомном десериализаторе.

Вы можете легко расширить с StdDeserializer<Document> и переопределить deserialize метод:

public class DocumentDeserializer extends StdDeserializer<Document> {

    @Override
    public Document deserialize(JsonParser p, DeserializationContext ctxt, Document value) throws IOException {

        JsonNode root = p.getCodec().readTree(p);
        JsonNode node = root.get("full_name");
        if(node.isArray()) {
            //get array data from node iterator then join as String and 
            //call setFirstName
        }
        return value;
    }
}

Тогда не забудьте позвонить registerModule из ObjectMapper, чтобы зарегистрировать deserializer

...