Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Json-запрос для получения ответа от сервера  [new]
wsnet
Member

Откуда:
Сообщений: 861
Ребята, с Json работаю впервые.
Имеется вопрос.
Накидал код для получения ответа, однако в ответ приходит пустой массив, а должен быть с полями и значениями.

procedure TForm1.Button1Click(Sender: TObject);
var
  PostData: TStringList;
  ResponseBody: string;
begin
  try
    PostData := TStringList.Create;
    PostData.Clear;
    PostData.Add(Utf8Encode('{"name": "никольское"}'));
    IdHTTP1.Request.ContentType := 'application/json';
    IdHTTP1.Request.Accept := 'application/json';
    IdHTTP1.Request.ContentEncoding := 'utf-8';
    ResponseBody := IdHTTP1.Post(
      'http://10.231.201.200/SstuRf/PublicApi/HandlingReport/SearchDepartments'
        , PostData);
    ShowMessage(IdHTTP1.ResponseText);
    ShowMessage(ResponseBody);
  finally
    PostData.Free;
  end;
end;


Хотя ответ от сервера имеет статус - HTTP/1.1 200 OK

Как понять в чем дело ?

Есть ли ПО для альтернативного получения? Чтобы хотя бы проверить что оно возвращает ?
20 июн 17, 15:28    [20577836]     Ответить | Цитировать Сообщить модератору
 Re: Json-запрос для получения ответа от сервера  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 3702
Связаться с разработчиками сервиса и узнать детали работы с ним. Из возможных косяков -- запрос идет почему-то через POST, хотя обычно такие вещи (чтение данных) как раз через GET делаются. Плюс, если это поиск, может надо еще какие настройки указывать (% в начале-конце поисковой строки) или там чуствителен к регистру он и тупо не находит никаких записей (мы ищем с маленькой буквы, а в базе он с большой).
20 июн 17, 15:44    [20577883]     Ответить | Цитировать Сообщить модератору
 Re: Json-запрос для получения ответа от сервера  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10578
wsnet,

wsnet
в ответ приходит пустой массив
Вероятнее всего сам запрос верный, но сервер не может найти такое значение. Варианты:
  • Его нет
  • Поиск регистрозависимый
  • Косяк с кодировкой запроса

    Косяков много. На сколько они фатальны - вопрос
    wsnet
      try
        PostData := TStringList.Create;
    
    Создавать объекты нужно ДО try
    wsnet
    PostData.Clear;
    
    Какой смысл очищать только-что созданный список?
    wsnet
    PostData.Add(Utf8Encode('{"name": "никольское"}'));
    
    А вот здесь уже серьезно. Если делфи юникодная, то в стринглист покладется строка в UTF-16. Как ее отправит инди - вопрос. Чтобы не заморачиваться с кодировками, пишите сразу в TStream и именно этот стрим отдавайте инди
    wsnet
    Как понять в чем дело ?
    Для начала смотреть в сниффере, что уходит на сервер
    wsnet
    Чтобы хотя бы проверить что оно возвращает ?
    В том же сниффере можно посмотреть и ответ
  • 20 июн 17, 17:02    [20578169]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    _Vasilisk_
    wsnet,

    wsnet
    в ответ приходит пустой массив
    Вероятнее всего сам запрос верный, но сервер не может найти такое значение. Варианты:
  • Его нет
  • Поиск регистрозависимый
  • Косяк с кодировкой запроса

    Косяков много. На сколько они фатальны - вопрос
    wsnet
      try
        PostData := TStringList.Create;
    
    Создавать объекты нужно ДО try
    wsnet
    PostData.Clear;
    
    Какой смысл очищать только-что созданный список?
    wsnet
    PostData.Add(Utf8Encode('{"name": "никольское"}'));
    
    А вот здесь уже серьезно. Если делфи юникодная, то в стринглист покладется строка в UTF-16. Как ее отправит инди - вопрос. Чтобы не заморачиваться с кодировками, пишите сразу в TStream и именно этот стрим отдавайте инди
    wsnet
    Как понять в чем дело ?
    Для начала смотреть в сниффере, что уходит на сервер
    wsnet
    Чтобы хотя бы проверить что оно возвращает ?
    В том же сниффере можно посмотреть и ответ


  • Vasilisk_ в точку! Огромное спасибо, после записи в Stream все получилось!
    procedure TForm1.Button1Click(Sender: TObject);
    var
      PostData: TStringStream;
      ResponseBody: string;
      Json: String;
    begin
      Json := '{"name": "никольское"}';
      PostData := TStringStream.Create(Utf8Encode(Json));
      try
        IdHTTP1.Request.ContentType := 'application/json';
        IdHTTP1.Request.Accept := 'application/json';
        IdHTTP1.Request.ContentEncoding := 'utf-8';
        ResponseBody := IdHTTP1.Post(
          'http://10.231.201.200/SstuRf/PublicApi/HandlingReport/SearchDepartments'
            , PostData);
        ShowMessage(IdHTTP1.ResponseText);
        ShowMessage(ResponseBody);
      finally
        PostData.Free;
      end;
    end;
    
    21 июн 17, 07:24    [20579222]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    Теперь не могу отправить json-запрос в видел файла на сервер.
    Запрос должен иметь вид:
    автор
    {
    "departmentId": "3DB1BE3B-BED1-49F6-AB4C-D138A81A9505",
    "isDirect": false,
    "format": "Electronic",
    "number": "А26-00-000000000",
    "createDate": "2016-11-15",
    "name": "Иванов Иван Иванович",
    "address": "г. Калуга, ул. Циолковского, д.8",
    "email": "user@hostname.com",
    "questions": [
    {
    "code": "0001",
    "status": "InWork",
    "incomingDate": "2016-11-16",
    "registrationDate": "2016-11-17"
    }
    ]
    }


    Пишу обработчик:
    procedure TForm1.Button2Click(Sender: TObject);
    var
      JSONObject: TJSONObject;
      JsonArray: TJSONArray;
      PostData: TStringStream;
    begin
      JSONObject := TJSONObject.Create;
      PostData := TStringStream.Create;
      try
        JSONObject.AddPair('departmentId',
          TJSONString.Create('715db6d9-0988-4ab0-8546-5a7783b1b362'));
        JSONObject.AddPair('isDirect', TJSONTrue.Create);
        JSONObject.AddPair('format', TJSONString.Create('Electronic'));
        JSONObject.AddPair('number', TJSONString.Create('1622'));
        JSONObject.AddPair('createDate', TJSONString.Create('2016-11-15'));
        JSONObject.AddPair('name', TJSONString.Create('Иванов Иван Иванович'));
        JSONObject.AddPair('address', TJSONString.Create
            ('г.Калуга, ул. Рознина, д.72'));
        JSONObject.AddPair('email', TJSONString.Create('mail@yandex.ru'));
        JsonArray := TJSONArray.Create();
        JSONObject.AddPair('questions', JsonArray);
        JsonArray.AddElement(TJSONObject.Create(TJSONPair.Create('code',
              TJSONString.Create('0001'))));
        JsonArray.AddElement(TJSONObject.Create(TJSONPair.Create('status',
              TJSONString.Create('InWork'))));
        JsonArray.AddElement(TJSONObject.Create(TJSONPair.Create('incomingDate',
              TJSONString.Create('2016-11-16'))));
        JsonArray.AddElement(TJSONObject.Create(TJSONPair.Create
              ('registrationDate', TJSONString.Create('2016-11-17'))));
    
        PostData.WriteString(JSONObject.ToString);
    
        PostData.SaveToFile('1.json');
    
      finally
        PostData.Free;
        JSONObject.Free;
      end;
    
    end;
    


    Получаю json-файл:
    {
    	"departmentId": "715db6d9-0988-4ab0-8546-5a7783b1b362",
    	"isDirect": true,
    	"format": "Electronic",
    	"number": "1622",
    	"createDate": "2016-11-15",
    	"name": "Иванов Иван Иванович",
    	"address": "г.Калуга, ул. Рознина, д.72",
    	"email": "mail@yandex.ru",
    	"questions": [{
    		"code": "0001"
    	}, {
    		"incomingDate": "2016-11-16"
    	}, {
    		"registrationDate": "2016-11-17"
    	}]
    }
    


    А далее пытаюсь отправить файл на тестовом стенде и получаю ошибку:
    Ошибка: Required property 'status' not found in JSON. Path 'questions[0]', line 1, position 267.
    


    Но свойство status стоит в нужном месте и определено в том же формате что и предлагается, почему так?
    21 июн 17, 12:51    [20580322]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    энди
    Member

    Откуда: Киров, Россия
    Сообщений: 898
    Возьмите библиотечку SuperObject, там синтаксис посахарнее :) Или вот этот форк если среда свежая https://github.com/onryldz/x-superobject
    21 июн 17, 13:03    [20580373]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    энди,

    А смысл брать другую библиотеку ?
    21 июн 17, 13:11    [20580396]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    энди
    Member

    Откуда: Киров, Россия
    Сообщений: 898
    Как бы вам ответить, для удобства работы и лучшей читаемости кода? Хотя если Вы привыкли работать На чистом winapi то да, не стоит :)
    21 июн 17, 13:20    [20580421]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    энди,

    меня просто интересует в чем ошибка в моем коде.
    21 июн 17, 13:22    [20580429]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    На выходе получается файл

    {"departmentId":"715db6d9-0988-4ab0-8546-5a7783b1b362","isDirect":true,"format":"Electronic","number":"1622","createDate":"2016-11-15","name":"Иванов Иван Иванович","address":"г.Москва, ул. Рознина, д.72","email":"mail@yandex.ru","questions":[{"code":"0001"},{"status":"InWork"},{"incomingDate":"2016-11-16"},{"registrationDate":"2016-11-17"}]}
    
    21 июн 17, 13:23    [20580435]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    энди
    Member

    Откуда: Киров, Россия
    Сообщений: 898
    ну тут вроде status есть
    21 июн 17, 14:04    [20580577]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    энди
    Member

    Откуда: Киров, Россия
    Сообщений: 898
    вы уверены что у вас questions вообще правильно задается, стремная запись если честно, логичнее было бы
    [{"code":"0001","status":"InWork","incomingDate":"2016-11-16","registrationDate":"2016-11-17"}]
    21 июн 17, 14:07    [20580593]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    энди,
    А как ее привести к такому виду?

    Вообще есть разница?

    Между
    "questions": [
    {
    "code": "0001",
    "status": "InWork",
    "incomingDate": "2016-11-16",
    "registrationDate": "2016-11-17"
    }
    ]
    


    и этим
    [{"code":"0001","status":"InWork","incomingDate":"2016-11-16","registrationDate":"2016-11-17"}]
    
    21 июн 17, 15:00    [20580837]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    и этим

    "questions": [{
    		"code": "0001"
    	}, {
    		"incomingDate": "2016-11-16"
    	}, {
    		"registrationDate": "2016-11-17"
    	}]
    
    21 июн 17, 15:01    [20580845]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    Все получилось, энди вы 100% были правы!

    procedure TForm1.Button2Click(Sender: TObject);
    var
      JSONObject: TJSONObject;
      JSONObject2: TJSONObject;
      JsonArray: TJSONArray;
      PostData: TStringStream;
    begin
      JSONObject := TJSONObject.Create;
      PostData := TStringStream.Create;
      try
        JSONObject.AddPair('departmentId',
          TJSONString.Create('715db6d9-0988-4ab0-8546-5a7783b1b362'));
        JSONObject.AddPair('isDirect', TJSONTrue.Create);
        JSONObject.AddPair('format', TJSONString.Create('Electronic'));
        JSONObject.AddPair('number', TJSONString.Create('1622'));
        JSONObject.AddPair('createDate', TJSONString.Create('2016-11-15'));
        JSONObject.AddPair('name', TJSONString.Create('Иванов Иван Иванович'));
        JSONObject.AddPair('address',
          TJSONString.Create('г.Калуга, ул. Рознина, д.72'));
        JSONObject.AddPair('email', TJSONString.Create('mail@yandex.ru'));
    
    
        JsonArray := TJSONArray.Create();
        JSONObject.AddPair('questions', JsonArray);
        JSONObject2 := TJSONObject.Create;
        JSONObject2.AddPair('code', TJSONString.Create('0001'));
        JSONObject2.AddPair('status', TJSONString.Create('InWork'));
        JSONObject2.AddPair('incomingDate', TJSONString.Create('2016-11-16'));
        JSONObject2.AddPair('registrationDate', TJSONString.Create('2016-11-17'));
        JsonArray.AddElement(JSONObject2);
    
        PostData.WriteString(JSONObject.ToString);
    
        PostData.SaveToFile('1.json');
    
      finally
        PostData.Free;
        JSONObject.Free;
      end;
    
    end;
    
    21 июн 17, 15:46    [20580999]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    wsnet
    Member

    Откуда:
    Сообщений: 861
    Выход
    {"departmentId":"715db6d9-0988-4ab0-8546-5a7783b1b362","isDirect":true,"format":"Electronic","number":"1622","createDate":"2016-11-15","name":"Иванов Иван Иванович","address":"г.Калуга, ул. Рознина, д.72","email":"mail@yandex.ru","questions":[{"code":"0001","status":"InWork","incomingDate":"2016-11-16","registrationDate":"2016-11-17"}]}
    
    21 июн 17, 15:47    [20581001]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    энди
    Member

    Откуда: Киров, Россия
    Сообщений: 898
    На здоровье, но на те библиотечки все же посмотрите, там код получается намного чище да и работать проще.
    21 июн 17, 16:45    [20581232]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    Петр
    Member

    Откуда: Москва
    Сообщений: 714
    Стоит аналогичная задача. Выполняю Post запрос
    procedure TForm1.Button1Click(Sender: TObject);
    var
      PostData: TStringStream;
      ResponseBody: string;
      Json: String;
    begin
      Json := '{"name": "никольское"}';
      PostData := TStringStream.Create(Utf8Encode(Json));
      try
        IdHTTP1.Request.ContentType := 'application/json';
        IdHTTP1.Request.Accept := 'application/json';
        IdHTTP1.Request.ContentEncoding := 'utf-8';
        ResponseBody := IdHTTP1.Post(
          'http://10.231.201.200/SstuRf/PublicApi/HandlingReport/SearchDepartments'
            , PostData);
        ShowMessage(IdHTTP1.ResponseText);
        ShowMessage(ResponseBody);
      finally
        PostData.Free;
      end;
    end;
    


    получаю ответ:
    [{"id":"30b54946-dfc8-e511-92f9-000c2903de7e","name":"??????? ??????? / ??????????? ??????? / ????????????? ?????? ??????????? ??????? / ????????????? ??????????? ?????????????? ?????? ??????????? ??????? / ???????? ????????? / ????????????? ?????????????? ??????????? \"???????? ????????? ??????????\" ??????????? ?????????????? ?????? ??????????? ??????? / ?????????????-???????????????? ?????? ?????????????? ??????????? / ????????????? ?????????????? ??????????? \"???????? ????????? ??????????\" ??????????? ?????????????? ?????? ??????????? ???????"},
    

    Как я понимаю проблема кодировкой. Но как ее победить не могу понять.
    Куда копать?
    9 июн 18, 15:22    [21482218]     Ответить | Цитировать Сообщить модератору
     Re: Json-запрос для получения ответа от сервера  [new]
    Петр
    Member

    Откуда: Москва
    Сообщений: 714
    Проблема решена. Для нуждающихся:
    procedure TForm1.Button10Click(Sender: TObject);
    var
      PostData: TStringStream;
      ResponseBody: String;
      Json: String;
    begin
      Json := '{"name": "никольское"}';
      PostData := TStringStream.Create(Utf8Encode(Json));
      try
        IdHTTP1.Request.ContentType := 'application/json';
        IdHTTP1.Request.Accept := 'application/json';
        IdHTTP1.Request.ContentEncoding := 'utf-8';
    
        ResponseBody := Utf8ToAnsi(IdHTTP1.Post('http://10.231.201.200/SstuRf/PublicApi/HandlingReport/SearchDepartments', PostData, IndyTextEncoding_UTF8));
        ShowMessage(IdHTTP1.ResponseText);
        ShowMessage(ResponseBody)
      finally
        PostData.Free;
      end;
    end;
    
    9 июн 18, 16:24    [21482367]     Ответить | Цитировать Сообщить модератору
    Все форумы / Delphi Ответить