Подтвердить что ты не робот

Как удалить ключ nameValuePairs из JSONObject?

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

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

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

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

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

UPDATE

Я не пытаюсь создать 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 автоматически добавляется к объекту.

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

4b9b3361

Ответ 1

Проблема:

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

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

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

Когда вы передаете JSONObject в аннотацию @Body, этот JSONObject является seraliazed, поэтому тело запроса 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);

Ответ 2

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

Определения

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

Инициализация

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

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

gsonResultDay.addProperty(epoch, 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}}

Ответ 3

Похоже, вы пытаетесь передать фактическое 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, не заботится о правильности пробелов.

Ответ 4

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

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));
         }
     }
}

Ответ 5

Вы должны преобразовать JSONObject в JsonObject

следовать по этому пути

 JsonParser jsonParser = new JsonParser();
  JsonObject jsonObject = (JsonObject)jsonParser.parse(actualjsonobject.toString());

затем пройти в теле

HashMap<String,Object> body=new HashMap();

 body.put("content",jsonObject);

Ответ 6

Используйте com.google.gson.JsonObject вместо org.json.JSONObject.

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

Изменить на

JsonObject jsonRequest = new JsonObject();
jsonRequest.addProperty("xxxx", "zzzzzzz");
jsonRequest.addProperty("yyyy", "uuuuuuu");

Тогда в интерфейсе

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

Класс JSONObject, хранящий значения в LinkedHashMap с именем переменной nameValuePairs Когда Gson пытается преобразовать экземпляр JSONObject в JSON, GSON сохраняет структуру (которая имеет переменную nameValuePairs). Это вызывает эту проблему.