В одном из моих приложений, в котором я использую библиотеку Loopj, мне нужно отправить сложный объект в веб-сервис (работающий на PHP). Я решил отправить объект JSON через HTTP-запрос POST, используя пример Loppj.
JSONObject params = new JSONObject();
try
{
params.put("params1", "value1");
params.put("params2", "value2");
params.put("params3", "value3");
}
catch(JSONException e)
{
// ...
}
StringEntity entity = new StringEntity(params.toString(), HTTP.UTF_8);
ArrayList<Header> array = new ArrayList<>();
array.add(new BasicHeader("Content-type", "application/json"));
array.add(new BasicHeader("Accept", "application/json"));
Header[] headers = new Header[headers.size()];
headers = headers.toArray(array);
AsyncHttpClient client = new AsyncHttpClient();
client.post(context, url, headers, entity, "application/json", new JsonHttpResponseHandler()
{
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response)
{
//...
}
@Override
public void onFailure(int statusCode, Header[] headers, Throwable e, JSONObject errorResponse)
{
// ...
}
});
К сожалению, $ _POST / $ _REQUEST всегда пусты. Я искал разные советы, но ни один из них не работает. У меня нет ограничений на маршруты в моем веб-сервисе, просто простая функция для выгрузки опубликованных параметров.
Чтобы проверить опубликованные параметры, я написал простую страницу PHP для их регистрации. Благодаря @Steve, я смог найти их в php://input
,
file_put_contents(__DIR__ . '/post_data.log', json_encode($_POST));
file_put_contents(__DIR__ . '/input_data.log', file_get_contents('php://input'));
Дело в том, что я не являюсь владельцем конечных веб-сервисов, поэтому не могу изменить доступ к данным. Они должны быть доступны через $ _POST. Итак, отправка заявки / JSON не является решением? Как AJAX может отправлять сложные объекты на сервер и находить их в $ _POST, а не в Android?
Я пытался сделать то же самое с PostMan, и $ _POST всегда пусто. Итак, я проанализировал запрос, отправленный jQuery.ajax (…) (который позволяет отправлять объект JSON), и он сгенерировал правильный ключ / значение из объекта JSON.
Например, объект JSON:
{
"users":[
{
"name":"jean",
"age":"25",
"city":"paris"}
]
}
Преобразовывается в 3 пары ключ / значение:
Итак, я предполагаю, что мне нужна функция, которая преобразует мой JSONObject в объект RequestParams и отправляет его «нормально» через «x-www-form-urlencoded». Я не знаю, есть ли какая-нибудь нативная функция, которая может сделать это, но я нашел эквивалент Javascript (Кодировка строки запроса объекта Javascript).
serialize = function(obj, prefix) {
var str = [], p;
for(p in obj) {
if (obj.hasOwnProperty(p)) {
var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
str.push((v !== null && typeof v === "object") ?
serialize(v, k) :
encodeURIComponent(k) + "=" + encodeURIComponent(v));
}
}
return str.join("&");
}
Как я уже говорил ранее, я написал вспомогательный класс, который преобразует JSONObject в RequestParams, который можно «нормально» отправлять через HTTP-метод POST.
Я скопировал / вставил его и написал быстрый файл README. Если у вас есть предложения или даже pull-запросы, пожалуйста, поделитесь.
Надеюсь, поможет.
Других решений пока нет …