web-dev-qa-db-ja.com

POJOを使用せずにGSONでjsonを変更する

JsonコンテンツをPOJOに変換せずに変更したい。 GSONライブラリを使用しています。

ユースケースは次のとおりです。

String jsonString = "[{\"key1\":\"Hello\",\"key2\":\"World\"},{\"key1\":\"Nice\",\"key2\":\"Town\"}]";

JsonElement jsonElement = gson.fromJson(jsonString, JsonElement.class);     

物事をPOJOに変換せずに、各配列でkey1の値をある値(「テスト」としましょう)に設定できる方法はありますか?

15
linuxeasy

これが私が思いついた最短のものです。

JsonElement je = new Gson().fromJson(jsonString, JsonElement.class);
JsonObject jo = je.getAsJsonObject();
jo.add("key", value);

JsonObjectを取得すると、gsonにはそれを操作するための多くのメソッドがあります。

9
Bruce Edge

いつでもJsonElementとは異なるタイプを取得するか、JsonElement.getAsJsonObjectを使用してオブジェクトにキャストできます(可能な場合)。

String jsonString = "[{\"key1\":\"Hello\",\"key2\":\"World\"}, ...]";

JsonArray jsonArray = gson.fromJson(jsonString, JsonElement.class).getAsJsonArray();
JsonObject firstObject = jsonArray.get(i).getAsJsonObject();
firstObject.addProperty("key1", "Test");

私は以前に間違っていました。 JsonArrayアダプタがないようです。 JsonElementを入手して、キャストツールを使用する必要があります。

2
Jeff Bowman

1つのアプローチは、JSONをJava.util.Mapに変換し、マップを変更して、そこから移動することです(これは、マップをJSONにシリアル化することを意味する場合があります)。

このアプローチは、適切なジョブに適切なAPIを使用して、シリアル化/逆シリアル化を処理するためのGsonなどのツールの使用を最小限に抑えるという私の好みを満たしています(これは、私が理解していることです)。つまり、GsonAPIを代替データ構造として使用しないことです。

2

GSONでjsonを変更するJsonArray Java 8

GSONを使用してJSON内の値を変更する方法の例

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class ModifyJson {
    public static void main(String[] args) {
        String data = "[{\"ct_pk\":24,\"ct_name\":\"SISTEMA DE PRUEBAS\"},"
                + "{\"ct_pk\":1,\"ct_name\":\"CAPITAL FEDERAL\"}," +
                "{\"ct_pk\":5,\"ct_name\":\"SISTEMA DE PRUEBAS DOS\"}]";

        System.out.println("before................." + data);

        JsonArray jsonArray = new Gson().fromJson(data, JsonElement.class).getAsJsonArray();
        JsonArray jsonArray2 = new JsonArray();
        for (JsonElement pa : jsonArray) {
            JsonObject jsonObject2 = pa.getAsJsonObject();
            String ct_name = jsonObject2.get("ct_name").getAsString();
            if (ct_name.equals("SISTEMA DE PRUEBAS")) {
                jsonObject2.addProperty("ct_name", "TODOS");
            }
            jsonArray2.add(jsonObject2);
        }
        System.out.println("after.................." +jsonArray2);
    }
}
0

JsonStringはプレーンで普通のJava String;なので、Javaの標準文字列関数を使用して好きなように変更し、部分文字列key1Test1に置き換えることができます。 :

jsonString = "[{\"key1\":\"Test\",\"key2\":\"World\"},{\"key1\":\"Nice\",\"key2\":\"Town\"}]";

もちろん、Javaの文字列は不変なので、最初にStringBuilderに変換すると、メモリ使用量の点でパフォーマンスが向上する可能性があります。

0
SylvainL

GSONには2つの別個のAPI(組み合わせることができます)があります。1つはシリアル化と逆シリアル化に使用され、もう1つはストリーミングに使用されます。メモリオーバーヘッドなしで、または(静的POJOではなく)動的構造を使用してJSONのストリームを処理する場合は、次のようにすることができます。

  • jsonWriterを作成します(私の例ではStringWriterを使用します)。
  • jsonReaderを作成します。
  • リーダーからのイベントを消費してライターにフィードするループを作成し、変更、追加、省略などを行う可能性があります。

ループは、考えられるすべてのイベント(そのうちの10個)に大文字と小文字を区別する必要がある単一のswitchステートメントで構成されます。最も単純な例でもすべてが含まれている必要があるため、以下のコードはかなり冗長に見えます。ただし、拡張は非常に簡単であり、さらに拡張してもそれほど長くなることはありません。

「test」を追加する例:各オブジェクトに1つのペアは次のようになります。

public class Whatever {

static void streamandmodify(JsonReader reader, JsonWriter writer) throws IOException {
    while (true) {
        JsonToken token = reader.peek();
        switch (token) {
        // most cases are just consume the event
        // and pass an identical one to the writer
        case BEGIN_ARRAY:
            reader.beginArray();
            writer.beginArray();
            break;
        case END_ARRAY:
            reader.endArray();
            writer.endArray();
            break;
        case BEGIN_OBJECT:
            reader.beginObject();
            writer.beginObject();

            // this is where the change happens:
            writer.name("test");
            writer.value(1);
            break;
        case END_OBJECT:
            reader.endObject();
            writer.endObject();
            break;
        case NAME:
            String name = reader.nextName();
            writer.name(name);
            break;
        case STRING:
            String s = reader.nextString();
            writer.value(s);
            break;
        case NUMBER:
            String n = reader.nextString();
            writer.value(new BigDecimal(n));
            break;
        case BOOLEAN:
            boolean b = reader.nextBoolean();
            writer.value(b);
            break;
        case NULL:
            reader.nextNull();
            writer.nullValue();
            break;
        case END_DOCUMENT:
            return;
        }
    }
}


public static void main(String[] args) throws IOException {
    // just for test:
    JsonReader jr = new JsonReader(new StringReader("{\"a\":1, \"b\":{\"c\":[1,2,3,{},{}]}}"));
    StringWriter sw = new StringWriter();
    JsonWriter jw = new JsonWriter(sw);
    streamandmodify(jr, jw);
    System.out.println(sw.getBuffer().toString());
}
}
0
fdreger