Как правильно обрабатывать демаршаллинг JSON, содержащий 'null', с помощью JAXB / MOXy? - PullRequest
0 голосов
/ 12 февраля 2019

Я создаю простое приложение JAXB / MOXy, которое получает информацию с сервера GitLab.Я просто хочу заполнить несколько полей информацией из ответа JSON API GitLab.

Я сделал несколько замечаний: всякий раз, когда в корневом объекте ответа есть значение «ноль», и этозначение не сохраняется ни в одном из полей моего POJO, весь неупорядоченный результат будет иметь значение 'null'.

Это работает, когда:
Значение 'null' находится во вложенном объекте.
The 'нулевое значение сохранено.

Я посмотрел и попробовал:

XmlNullPolicy (emptyNodeRepresentsNull = true/false, isSetPerformedForAbsentNode = true/false, xsiNilRepresentsNull = true/false)

, но, похоже, он не справляется с тем, что мне здесь интересно.

POJO:


@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class GitlabProject implements GitlabItem {

    @XmlAttribute(name="id")
    private Long projectId;
    @XmlAttribute(name="name")
    private String projectName;

    @XmlElement(nillable=true)
    @XmlAttribute(name="description")
    private String projectDescription;

    // getters, setters

    public GitlabProject() {}

    public GitlabProject(Long id, String name, String description) {
        this.projectId = id;
        this.projectName = name;
        this.projectDescription = description;
    }

    @Override
    public  String toString() {
        return "GitlabProject {\n" +
                "    projectId: " + projectId + "\n" +
                "    projectName: " + projectName + "\n" +
                "    projectDescription: " + projectDescription + "\n" +
                "}";
    }
}

Пример ответа GitLab, который приводит к «нулю»:

{
  "id": 69,
  "description": "A surefire plan to achieve Hello World Peace",
  "name": "Hello World Peace",
  "name_with_namespace": "world / peace",
  "path": "peace",
  "path_with_namespace": "world/peace",
  "created_at": "2019-01-01T12:12:43.836Z",
  "default_branch": "master",
  "tag_list": [],
  "ssh_url_to_repo": "XXXXXXXXXXXXXXXXXXXXXXXXXx",
  "http_url_to_repo": "XXXXXXXXXXXXXXXXXXXx",
  "web_url": "XXXXXXXXXXXXXXXXXXXXX,

  "avatar_url": "asdfasdfasdf",
  "star_count": 0,
  "forks_count": null,
  "last_activity_at": "2019-02-11T12:20:43.836Z",
  "namespace": {
    "id": 6,
    "name": "peace",
    "path": "peace",
    "kind": "group",
    "full_path": "group"
  }
}

Значение для «forks_count» равно «нулю».
Результат:

null

Примерответа GitLab, который приводит к тому, что я хочу:

{
  "id": 69,
  "description": "A surefire plan to achieve Hello World Peace",
  "name": "Hello World Peace",
  "name_with_namespace": "world / peace",
  "path": "peace",
  "path_with_namespace": "world/peace",
  "created_at": "2019-01-01T12:12:43.836Z",
  "default_branch": "master",
  "tag_list": [],
  "ssh_url_to_repo": "XXXXXXXXXXXXXXXXXXXXXXXXXx",
  "http_url_to_repo": "XXXXXXXXXXXXXXXXXXXx",
  "web_url": "XXXXXXXXXXXXXXXXXXXXX,

  "avatar_url": "asdfasdfasdf",
  "star_count": 0,
  "forks_count": 6,
  "last_activity_at": "2019-02-11T12:20:43.836Z",
  "namespace": {
    "id": 6,
    "name": "peace",
    "path": "peace",
    "kind": "group",
    "full_path": null
  }
}

Значение «full_path» во вложенном объекте пространства имен равно «null».
Результат:

GitlabProject {
    projectId: 69
    projectName: Hello World Peace
    projectDescription: A surefire plan to achieve Hello World Peace
}

Пример другого ответа GitLab, который приводит к тому, что я хочу:

{
  "id": 69,
  "description": "A surefire plan to achieve Hello World Peace",
  "name": null,
  "name_with_namespace": "world / peace",
  "path": "peace",
  "path_with_namespace": "world/peace",
  "created_at": "2019-01-01T12:12:43.836Z",
  "default_branch": "master",
  "tag_list": [],
  "ssh_url_to_repo": "XXXXXXXXXXXXXXXXXXXXXXXXXx",
  "http_url_to_repo": "XXXXXXXXXXXXXXXXXXXx",
  "web_url": "XXXXXXXXXXXXXXXXXXXXX,

  "avatar_url": "asdfasdfasdf",
  "star_count": 0,
  "forks_count": 6,
  "last_activity_at": "2019-02-11T12:20:43.836Z",
  "namespace": {
    "id": 6,
    "name": "peace",
    "path": "peace",
    "kind": "group",
    "full_path": null
  }
}

Значение поля 'name', которое я хочу сохранить, равно 'null'.
Результат:

GitlabProject {
    projectId: 69
    projectName: null
    projectDescription: A surefire plan to achieve Hello World Peace
}

Вот код, который я использую для демонтажа ответа (в модульном тесте)

public class MarshallingUnmarshallingTests {
    private GitlabProject projectU;


    @Before
    public void setup() {
    }

    @After
    public void tearDown() {
        projectU = null;
    }

    @Test
    public void testJsonToObject() throws JAXBException, FileNotFoundException {
        File file = new File("GitlabProjectResponse.json");
        StreamSource json = new StreamSource(file);

        Map<String, Object> properties = new HashMap<String, Object>(2);
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);

        JAXBContext jaxbContext = JAXBContext.newInstance(new Class[]{GitlabProject.class}, properties);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

        projectU = unmarshaller.unmarshal(json, GitlabProject.class).getValue();
        System.out.println(projectU);
    }
}

Я перечитал много документации и примеров, но в основном я нашел объяснения для представлений 'аннотации null 'и nillable.

Заранее благодарим за каждый ответ!

...