Согласно этому сообщению, возврат пустой список должен обрабатывать нули. Но в моем случае он все еще жалуется, что чего-то ожидает, но не нашел. Вот мой класс:

public class PersonProfile {

        public class PhoneDetails {
            public String cust_phone_id;
            public String phone_type;
            public String phone_type_primary_ind;
            public String phone_number;
            public String solicit_phone;
            public String mobile_text_messages_allowed;
        }

        public List<RECORD> RECORD;

        public class AddressDetails {
            public String cust_address_id;
            public String address_type;
            public String primary_ind_address;
            public String address_type_primary_ind;
            public String street_addr_1;
            public String street_addr_2;
            public String city;
            public String state;
            public String zip;
            public String country;
            public String company_address_ind;
            public String solicit_mail;
        }

        public class RECORD {
            public String cust_name_id;
            public String email_id;
            public String email_type;
            public String email_addr;
            public String primary_ind_email;
            public String solicit_email;
            public String name_type;
            public String name_first;
            public String name_middle;
            public String name_last;
            public String full_name;
            public String name_suffix;
            public String name_title;
            public String company_name;
            public String gender;
            public String add_datetime;
            public String upd_datetime;
            public List<PhoneDetails> PhoneDetails { get {
                return PhoneDetails == null ? new List<PhoneDetails>() : PhoneDetails;
                } set;
            }
            public List<AddressDetails> AddressDetails { get {
                return AddressDetails == null ? new List<AddressDetails>() : AddressDetails;
                } set;
            }
        }
    }

Вот JSON:

{
    "RECORD": [
        {
            "cust_name_id": "3594720",
            "name_type": "I",
            "name_first": "Count",
            "name_middle": null,
            "name_last": "Ravioli",
            "full_name": "Count Ravioli",
            "name_suffix": null,
            "name_title": null,
            "company_name": null,
            "add_datetime": "2020-01-15T09:59:20.173-05:00",
            "upd_datetime": "2020-01-15T09:59:20.173-05:00",
            "PhoneDetails": [
                null
            ],
            "AddressDetails": [
                {
                    "cust_address_id": "4539116",
                    "address_type": "H",
                    "primary_ind_address": "Y",
                    "address_type_primary_ind": "Y",
                    "street_addr_1": null,
                    "street_addr_2": null,
                    "city": null,
                    "company_address_ind": "N",
                    "solicit_mail": "N"
                }
            ]
        }
    ]
}

И вот как я это называю:

public static IntegrationWebService.Response createProfileRegistration(RestRequest req, RestResponse res) {

    String errorMessage;

    Exception exceptionResult;
    Boolean errorsFound = false;

    try {
        PersonProfile  profile = new PersonProfile ();
        profile = (PersonProfile ) System.JSON.deserialize(req.requestBody.toString(), PersonProfile.class);

        for (PersonProfile.RECORD p : profile.RECORD){      

        //Do a bunch of things...
       }

     }
    catch(Exception e){
        System.debug('ERROR: ' + e);
        String exType = e.getTypeName();
        String exMessage = e.getMessage();

        exceptionResult = e;
        errorsFound = true;        
    }
}

Эта строка выдает ошибку, однако, если я удаляю нуль и передаю пустой массив, он вообще не жалуется и обрабатывает запись. Как я могу правильно обрабатывать нули без передачи пустых массивов?

 profile = (PersonProfile ) System.JSON.deserialize(req.requestBody.toString(), PersonProfile.class);

Ошибка: "errorMessage": "Expected PersonProfile.PhoneDetails but found null at [line:16, column:5]"

1
SavvyGoat 23 Янв 2020 в 00:44
Пустой массив будет правильной семантикой или просто значением null для свойства PhoneDetails. У вас есть контроль над вводом JSON?
 – 
cropredy
23 Янв 2020 в 00:48
Да, я контролирую ввод. Так что лучше всего было бы передать пустой массив вместо нуля?
 – 
SavvyGoat
23 Янв 2020 в 00:53
Да --- либо пустой массив, либо значение свойства вообще отсутствует (и ваш геттер преобразуется в пустой массив)
 – 
cropredy
23 Янв 2020 в 00:55
Вы должны были добавить ответ на этот счет?
 – 
sfdcfox
23 Янв 2020 в 04:50

1 ответ

Лучший ответ

Поскольку у вас есть контроль над вводом JSON, есть три способа выразить пустой список:

Вариант 1

{
"RECORD": [
      {
        ...
        "PhoneDetails": [],
        ...
      }
   ]
 }

В этом случае значением свойства PhoneDetails будет пустой список PhoneDetails объектов (кроме того, этот внутренний класс следует называть PhoneDetail, поскольку он является объектом один телефон)

Вариант 2

{
"RECORD": [
      {
        ...
        "PhoneDetails": null,
        ...
      }
   ]
 }

Вариант 3. Просто исключите свойство PhoneDetails из полезной нагрузки. Оно будет десериализовано как null в свойство PhoneDetails в родительском объекте RECORD.

В вариантах 2 и 3 вам нужен геттер для свойства PhoneDetails, как вы закодировали в OP:

public List<PhoneDetails> PhoneDetails { 
   get {
        return PhoneDetails == null ? new List<PhoneDetails>() : PhoneDetails;
        } set;
}

Что касается защитного программирования, я бы предположил, что вариант 3 в Apex и все варианты 1-2-3 приемлемы и будут правильно десериализоваться. Все остальное является нарушением контракта JSON между издателем и потребителем этой полезной нагрузки.

1
cropredy 23 Янв 2020 в 05:23