Jackson ObjectMapper не читает внутренние объекты

У меня есть файл JSON

{
    "readServiceAuthorizationResponse": {
        "serviceAuthorization": {
            "serviceAuthorizationId": "50043~220106065198",
            "status": "Approved",
            "receivedDate": "2022-1-6 1:21:12 PM",
            "providerFirstName": "Ranga",
            "providerLastName": "Thalluri",
            "organizationName": "General Hospital",
            "serviceLines": [{
                "statusReason": "Approved",
                "procedureDescription": "Room & board ward general classification",
                "requestedQuantity": "1.00",
                "approvedQuantity": "1.00",
                "deniedQuantity": "",
                "quantityUnitOfMeasure": "Day(s)",
                "providers": [{
                    "providerFirstName": "Ranga",
                    "providerLastName": "Thalluri",
                    "organizationName": ""
                }]
            }]
        }
    }
}

Моя Java для чтения этого в объект такова:

package com.shawn.dto;

import java.nio.file.Files;
import java.nio.file.Paths;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;

@JsonIgnoreProperties(ignoreUnknown = true)
public class ServiceAuthorizationDTO {
    public String serviceAuthorizationId;
    public String status;
    public String receivedDate;
    public String providerFirstName;
    public String providerLastName;
    public String organizationName;
    public ServiceLine[] serviceLines;
    
    public static ServiceAuthorizationDTO create(String json) {
        ObjectMapper m = new ObjectMapper();
        try {
            Outer outer = m.readValue(json, Outer.class);
            return outer.readServiceAuthorizationResponse.serviceAuthorization;
        } catch (Exception e) {
            return null;
        }
    }
    
    @JsonIgnoreProperties(ignoreUnknown = true)
    static class ReadServiceAuthorizationResponse {
        public ServiceAuthorizationDTO serviceAuthorization;        

    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    static class Outer {
        public ReadServiceAuthorizationResponse readServiceAuthorizationResponse;       
        
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ServiceLine {
        String statusReason;
        String procedureDescription;
        String requestedQuantity;
        String approvedQuantity;
        String deniedQuantity;
        String quantityUnitOfMeasure;
        Provider[] providers;
        
    }
    
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Provider {
        String providerFirstName;
        String providerLastName;
        String organizationName;

    }
    
    public static void main(String[] args) {
        try {
            String json = new String(Files.readAllBytes(Paths.get("c:/temp/test.json")));
            ServiceAuthorizationDTO dao = ServiceAuthorizationDTO.create(json);
            System.out.println("serviceAuthorizationId: " + dao.serviceAuthorizationId);
            System.out.println("serviceLines[0].procedureDescription: " + dao.serviceLines[0].procedureDescription);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
    
}

Когда я запускаю его, я получаю это:

serviceAuthorizationId: 50043~220106065198
serviceLines[0].procedureDescription: null

Внешние поля в объекте, такие как providerId, считываются из JSON. Но массив serviceLines показывает 1 элемент, и все поля в этом классе пусты.

Любые идеи? Это первый раз, когда я использовал настоящие объекты с JSON. Я всегда сопоставлял его с объектами карты и вытаскивал поля вручную. Спасибо.

Может это поможет: stackoverflow.com/questions/27895376/…

happy songs 30.03.2022 01:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поля в классах ServiceLine и Provider имеют модификаторы доступа package-private. Джексон не может десериализовать в частные поля с настройками по умолчанию. Потому что ему нужны методы получения или установки.

Решение 1. Сделайте поля общедоступными

    public static class ServiceLine {
        public String statusReason;
        public String procedureDescription;
        public String requestedQuantity;
        public String approvedQuantity;
        public String deniedQuantity;
        public String quantityUnitOfMeasure;
        public Provider[] providers;        
    }

Решение 2. Используйте аннотацию @JsonAutoDetect

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class ServiceLine {
    String statusReason;
    String procedureDescription;
    String requestedQuantity;
    String approvedQuantity;
    String deniedQuantity;
    String quantityUnitOfMeasure;
    Provider[] providers;
}

Решение 3. Изменить видимость в ObjectMapper (документ)

    public static ServiceAuthorizationDTO create(String json) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
            Outer outer = objectMapper.readValue(json, Outer.class);
            return outer.readServiceAuthorizationResponse.serviceAuthorization;
        } catch (Exception e) {
            return null;
        }
    }

Решение 4. Добавьте геттер/сеттер :)

Alper Derya 30.03.2022 01:29

Лучшее решение :) Спасибо!!

Eugene 30.03.2022 01:36

Спасибо. Я ценю помощь, и я должен был знать об общедоступности :) У меня были общедоступные только некоторые поля, и они работали. Ну, я чувствую себя застенчивым (Baaaa).

shawnlg 30.03.2022 16:39

Другие вопросы по теме