Как преобразовать строку, разделенную запятыми на карте, в набор в объекте, используя Джексон в Java - PullRequest
1 голос
/ 07 мая 2020

Я запускаю следующую программу:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {

    private static class Shape {
        private String name;
        private Set<String> colors;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Set<String> getColors() {
            return colors;
        }

        public void setColors(Set<String> colors) {
            this.colors = colors;
        }
    }

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> attributes = new HashMap<>();
        attributes.put("name", "table");
        attributes.put("colors", "blue,green,red,black");
        Shape shape = objectMapper.convertValue(attributes, Shape.class);
    }
}

Здесь зависимости в pom. xml:

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.9.3</version>
        </dependency>
    </dependencies>

У меня следующая ошибка:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot deserialize instance of `java.util.HashSet` out of VALUE_STRING token
 at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.company.test.Test$Shape["colors"])
    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3751)
    at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3669)
    at com.company.test.Test.main(Test.java:36)

Я попытался изменить на:

    attributes.put("colors", "[blue,green,red,black]");
    AND
    attributes.put("colors", "[\"blue\",\"green\",\"red\",\"black\"]");

Но это не работает. Обходной путь может быть следующим:

    ...
    Set<String> colors = new HashSet<>();
    colors.add("blue");
    colors.add("green");
    colors.add("red");
    colors.add("black");
    attributes.put("colors", colors);
    ...

Однако это решение не разрешено для текущей реализации. Вы представляете, как реализовать другой подход?

1 Ответ

1 голос
/ 07 мая 2020

Вы можете использовать CsvMapper из библиотеки jackson-dataformats-text . Кроме того, вам нужно сначала десериализовать String в Set<String>, построить Map и преобразовать его в Shape в конце:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class CsvApp {
    public static void main(String[] args) throws JsonProcessingException {
        CsvMapper mapper = new CsvMapper();

        String array = "blue,green,red,black";
        Map<String, Object> attributes = new HashMap<>();
        attributes.put("name", "table");
        attributes.put("colors", mapper.readValue(array, new TypeReference<Set<String>>() {}));
        Shape shape = mapper.convertValue(attributes, Shape.class);

        System.out.println(shape);
    }
}
...