Что такое body в HTTP
Что проверяют
Понимаете ли вы, из чего состоит HTTP-сообщение, и как это ложится на клиентские библиотеки Android. Вопрос выглядит словарным, но спрашивают ради практики: откуда берётся Content-Type, почему тело читается один раз и что приходит в ответе с ошибкой.
Как отвечать
Сообщение HTTP состоит из стартовой строки, заголовков, пустой строки и необязательного тела. Тело это полезная нагрузка: JSON, поля формы, файл, кусок медиа. Что именно внутри, говорят заголовки: Content-Type задаёт формат и кодировку, Content-Length или chunked-передача задают длину.
Тело есть не у всех сообщений. У GET его обычно нет, семантика не определена и промежуточные узлы могут его выбросить. У ответов со статусом 204 и 304 тела нет по спецификации, у ответа на HEAD тоже, хотя заголовки приходят как у обычного ответа.
Android-специфика, которую и ждут услышать. В OkHttp тело запроса это RequestBody: JSON-строка с типом, FormBody для обычной формы, MultipartBody для загрузки файла. Тело ответа это ResponseBody, и у него два правила. Оно читается один раз, потому что за ним стоит поток, и его нужно закрыть, иначе соединение утечёт. При неуспешном коде Retrofit кладёт тело не в успешный результат, а в отдельное поле ошибки, и читать его нужно оттуда.
Где спотыкаются
Читают тело ответа дважды: сначала в перехватчике для лога, потом в конвертере. Второй вызов получает пустоту, потому что поток уже исчерпан; для логирования есть готовый перехватчик, который делает копию аккуратно.
Считают, что тело всегда JSON. Сервер может вернуть HTML страницы ошибки от прокси или пустое тело, и парсер падает на первом символе. Проверять надо код ответа и тип содержимого, а не сразу разбирать.
Не разбирают тело ошибочного ответа и показывают пользователю общую фразу про неизвестный сбой, хотя сервер прислал точную причину. Заодно тянут гигантский файл целиком в строку и получают падение по памяти вместо чтения потоком.