it-swarm.com.ru

Как я могу удалить ключ nameValuePairs из JSONObject?

Я работаю над проектом Android, которому нужен JSONObject для тела моего запроса POST . После помещения ключей и значений JSON я получил следующую строку:

{
    "xxxx":"zzzzzzz",
    "yyyy":"uuuuuuu"
}

Но сервер получил следующее:

{
    "name_value_pairs": {
                        "xxxx":"zzzzzzz",
                        "yyyy":"uuuuuuu"
    }
}

Я уже попробовал JSONStringer, но это не очень помогло, потому что Content-Type запроса - application/json.

ОБНОВЛЕНИЕ

Я не пытаюсь создать JSONObject, потому что это уже сделано с использованием следующей строки кода (то же самое, что @osayilgan):

JSONObject jsonRequest = new JSONObject();
jsonRequest.put("xxxx", "zzzzzzz");
jsonRequest.put("yyyy", "uuuuuuu");

Здесь не проблема. Описанный ниже интерфейс используется для связи с сервером.

public interface MyService {
    @Headers({"Content-type: application/json",
              "Accept: */*"})
    @POST("/test")
    void testFunction(@Body JSONObject jsonObject, Callback<Response> callback);
}

Сервер получил запрос со вторым JSON как Body, что разочаровывает. Отмечу, что ключ name_value_pairs автоматически добавляется к объекту.

Кто-нибудь знает, как я могу это исправить?

20
13KZ

Issue

Модификация по умолчанию использует GSON для преобразования тел HTTP в и из JSON. Объект, указанный с помощью аннотации @Body, будет передан в GSON для сериализации, которая в основном преобразует объект Java в представление JSON. Это представление JSON будет телом HTTP-запроса.

JSONObject хранит все сопоставления ключ-значение в переменной-члене с именем nameValuePairs. Вот выдержка из реализации JSONObject:

public class JSONObject {
    ...
    private final Map<String, Object> nameValuePairs;
    ...
}

Когда вы передаете JSONObject аннотации @Body, этот JSONObject разделяется, поэтому тело HTTP-запроса содержит: {"nameValuePairs": "фактический объект JSON"}.

Решение: 

Передайте реальный объект Java аннотации @Body, а не соответствующий JSONObject. GSON позаботится о преобразовании его в представление JSON.

Например,.

class HTTPRequestBody {
   String key1 = "value1";
   String key2 = "value2";
   ...
}

// GSON will serialize it as {"key1": "value1", "key2": "value2"}, 
// which will be become HTTP request body.

public interface MyService {
    @Headers({"Content-type: application/json",
              "Accept: */*"})
    @POST("/test")
    void postJson(@Body HTTPRequestBody body, Callback<Response> callback);
}

// Usage
MyService myService = restAdapter.create(MyService.class);
myService.postJson(new HTTPRequestBody(), callback);

Альтернативное решение:

Если вы все еще хотите отправить необработанный JSON в качестве тела HTTP-запроса, следуйте решению, указанному автором Retrofit здесь .

Одним из предложенных решений является использование TypedInput :

public interface MyService {
  @POST("/test")
  void postRawJson(@Body TypedInput body, Callback<Response> callback);
}

String json = jsonRequest.toString();
TypedInput in = new TypedByteArray("application/json", json.getBytes("UTF-8"));
myService.postRawJson(in, callback);
23
Manish Mulimani

Благодаря 13KZ, указал мне верное направление, и, чтобы уточнить это здесь, я должен решить эту проблему.

Определения

private JsonObject gsonResultTwoWeek;
private JsonObject gsonResultDay;
private JsonObject gsonResult;

Инициализировать

gsonResult = new JsonObject();
gsonResultDay = new JsonObject();
gsonResultTwoWeek = new JsonObject();

Использование

gsonResultDay.addProperty(Epoch, value);

где data это строка, а value это int в моем случае и находится в цикле for для добавления нескольких значений

А потом собрать все вместе

gsonResult.addProperty("accounts", 2);
gsonResult.add("todaydata", gsonResultDay);
gsonResult.add("2weekdata", gsonResultTwoWeek);

Наконец мой интерфейс

public interface ApiInterface {

    @POST("/groupdata")
    void postGroupData(@Body JsonObject body,Callback<StatusResponse> cb);

}

Что поражает мой сервер это

{"accounts":2,"todaydata":{"1423814400":89,"1423816200":150,"1423818000":441},"2weekdata":{"1423699200":4869,"1423785600":1011}}
1
Longmang

Мое решение основано на 13KZ

public class MyRequest {

  @SerializedName(Constants.ID)
  private String myID;
  @SerializedName(Constants.PARAM_ANSWERS)
  private JsonObject answers;

     public MyRequest(String id, Hasmap<String, String> answers) {
         this.myID = id;
         this.answers = new JsonObject();
         for (String s: answers.keySet()) {
             this.answers.addProperty(s, answers.get(s));
         }
     }
}
0
Fran

Похоже, вы пытаетесь передать фактическую переменную JSONObject, а не текстовое представление JSON объекта. Изучение спецификации для класса JSONObject показывает, что вы должны использовать метод .toString() , чтобы получить текстовое представление JSON структуры данных, хранящейся в переменной JSONObject. Таким образом, вы должны быть в состоянии изменить:

public interface MyService {
    @Headers({"Content-type: application/json",
              "Accept: */*"})
    @POST("/test")
    void testFunction(@Body JSONObject jsonObject, Callback<Response> callback);
}

чтобы:

public interface MyService {
    @Headers({"Content-type: application/json",
              "Accept: */*"})
    @POST("/test")
    void testFunction(@Body String jsonObject.toString(), Callback<Response> callback);
}

Единственным изменением является JSONObject jsonObject на String jsonObject.toString().

С другой стороны, вы можете перебором, просто взяв имеющуюся у вас строку JSON и заменив '"name_value_pairs": {' на '', а последний '}' в строке на ''. JSON - это просто строка текста. Кроме того, что это не элегантно, нет никаких причин, по которым вы не можете манипулировать текстом. Эти две замены приведут к действительному текстовому объекту JSON. Отступы для пробелов не будут выглядеть корректно для человека, но машина, анализирующая строку JSON, не заботится о правильности пробелов.

0
Makyen