Gson - แปลงจาก Json เป็น ArrayList ที่พิมพ์ <T>


211

การใช้ไลบรารี Gson ฉันจะแปลงสตริง JSON ArrayListเป็นคลาสที่กำหนดเองได้JsonLogอย่างไร โดยพื้นฐานแล้วJsonLogเป็นอินเทอร์เฟซที่ใช้งานโดยบันทึกต่าง ๆ ที่ทำโดยแอพ Android ของฉัน - บันทึก SMS, บันทึกการโทร, บันทึกข้อมูล - และนี่ArrayListคือชุดทั้งหมดของพวกเขา ฉันได้รับข้อผิดพลาดในบรรทัดที่ 6 ต่อไป

public static void log(File destination, JsonLog log) {
    Collection<JsonLog> logs = null;
    if (destination.exists()) {
        Gson gson = new Gson();
        BufferedReader br = new BufferedReader(new FileReader(destination));
        logs = gson.fromJson(br, ArrayList<JsonLog>.class); // line 6
        // logs.add(log);
        // serialize "logs" again
    }
}

ArrayListดูเหมือนว่าคอมไพเลอร์ไม่เข้าใจผมหมายถึงพิมพ์ ฉันจะทำอย่างไร


โปรดอ้างอิงstackoverflow.com/questions/44589381//สำหรับวิธีการอื่น
Pankaj Jaiswal

คำตอบ:


515

คุณอาจใช้TypeTokenเพื่อโหลดสตริง json ลงในวัตถุที่กำหนดเอง

logs = gson.fromJson(br, new TypeToken<List<JsonLog>>(){}.getType());

เอกสารอ้างอิง:

หมายถึงประเภททั่วไปT

Java ยังไม่มีวิธีในการแสดงประเภททั่วไปดังนั้นคลาสนี้ทำ บังคับให้ไคลเอนต์สร้างคลาสย่อยของคลาสนี้ซึ่งเปิดใช้งานการดึงข้อมูลชนิดแม้ที่รันไทม์

ตัวอย่างเช่นในการสร้างประเภทตัวอักษรสำหรับList<String>คุณสามารถสร้างคลาสภายในที่ไม่ระบุชื่อที่ว่างเปล่า:

TypeToken<List<String>> list = new TypeToken<List<String>>() {};

ไวยากรณ์นี้ไม่สามารถใช้ในการสร้างตัวอักษรชนิดที่มีพารามิเตอร์ตัวแทนเช่นหรือClass<?>List<? extends CharSequence>

Kotlin:

ถ้าคุณต้องการทำในKotlinคุณสามารถทำได้เช่นนี้:

val myType = object : TypeToken<List<JsonLong>>() {}.type
val logs = gson.fromJson<List<JsonLong>>(br, myType)

หรือคุณสามารถดูคำตอบนี้สำหรับทางเลือกต่าง ๆ


3
ลองใช้วิธีนี้และฉันได้รับข้อผิดพลาดในการรวบรวมว่า TypeToken () มีการป้องกันการเข้าถึงเท่านั้น
Jonathan

1
@ Jonney ฉันมีปัญหาเดียวกัน ทางออกใด ๆ ?
Zapnologica

15
หากคุณได้รับการป้องกันข้อผิดพลาดการเข้าถึงคุณออก{ }ก่อน.getType()
Zapnologica

@Alex ทำ deserialize ก่อนเป็น Array แล้ว Array นั้นถูกแปลงเป็น List หรือไม่หรือทำให้ deserialize เป็น List โดยตรง?
Adnan Ali

วัวทั้งหมด! ฉันจะคิดได้ว่าเช่น ... ดี ... ไม่เคย ขอบคุณ.
John Ward

26

ตัวอย่าง JSON ของคุณคือ:

{
    "status": "ok",
    "comment": "",
    "result": {
    "id": 276,
    "firstName": "mohamed",
    "lastName": "hussien",
    "players": [
            "player 1",
            "player 2",
            "player 3",
            "player 4",
            "player 5"
    ]
}

ดังนั้นหากคุณต้องการบันทึก arraylist ของโมดูลใน SharedPrefrences ของคุณ:

1- จะแปลง arraylist ส่งคืนของคุณสำหรับรูปแบบ json โดยใช้วิธีนี้

public static String toJson(Object jsonObject) {
    return new Gson().toJson(jsonObject);
}

2- บันทึกไว้ใน prefreneces ที่ใช้ร่วมกัน

PreferencesUtils.getInstance(context).setString("players", toJson((.....ArrayList you want to convert.....)));

3- เพื่อเรียกคืนได้ตลอดเวลารับ JsonString จากการตั้งค่าที่ใช้ร่วมกันเช่นนั้น

String playersString= PreferencesUtils.getInstance(this).getString("players");

4- แปลงอีกครั้งเพื่อรายการอาร์เรย์

public static Object fromJson(String jsonString, Type type) {
    return new Gson().fromJson(jsonString, type);
}

ArrayList<String> playersList= (ArrayList<String>) fromJson(playersString,
                    new TypeToken<ArrayList<String>>() {
                    }.getType());

การแก้ปัญหานี้ยังเป็นไปได้ถ้าคุณต้องการที่จะแยก ArrayList ของวัตถุหวังว่ามันจะช่วยให้คุณโดยใช้ห้องสมุด Gson


นี่เป็นทางออกที่ถูกต้อง แต่โดยพื้นฐานแล้วเหมือนกับคำตอบที่เก่ากว่าสามปีที่มีข้อมูลที่ไม่จำเป็นจำนวนมาก - ฉันไม่ได้มาที่นี่เพื่อเรียนรู้เกี่ยวกับการแชร์แบบกำหนดเอง
Xerus

8

ถ้าคุณต้องการใช้อาร์เรย์มันค่อนข้างง่าย

logs = gson.fromJson(br, JsonLog[].class); // line 6

ระบุJsonLogเป็นอาร์เรย์JsonLog[].class


8

Kotlin

data class Player(val name : String, val surname: String)

val json = [
  {
    "name": "name 1",
    "surname": "surname 1"
  },
  {
    "name": "name 2",
    "surname": "surname 2"
  },
  {
    "name": "name 3",
    "surname": "surname 3"
  }
]

val typeToken = object : TypeToken<List<Player>>() {}.type
val playerArray = Gson().fromJson<List<Player>>(json, typeToken)

หรือ

val playerArray = Gson().fromJson(json, Array<Player>::class.java)

5

ทำไมไม่มีใครเขียนนี้วิธีที่ง่ายของการแปลงสตริง JSON ในรายการ ?

List<Object> list = Arrays.asList(new GsonBuilder().create().fromJson(jsonString, Object[].class));

1

ฉันไม่แน่ใจเกี่ยวกับ gson แต่นี่เป็นวิธีที่คุณทำกับ Jon.sample หวังว่าจะต้องมีวิธีการที่คล้ายกันโดยใช้ gson

{"ผู้เล่น": ["ผู้เล่น 1", "ผู้เล่น 2", "ผู้เล่น 3", "ผู้เล่น 4", "ผู้เล่น 5"]}

===============================================

import java.io.FileReader;
import java.util.List;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

public class JosnFileDemo {

    public static void main(String[] args) throws Exception
    {
        String jsonfile ="fileloaction/fileName.json";


                FileReader reader = null;
                JSONObject jsb = null;
                try {
                    reader = new FileReader(jsonfile);
                    JSONParser jsonParser = new JSONParser();
                     jsb = (JSONObject) jsonParser.parse(reader);
                } catch (Exception e) {
                    throw new Exception(e);
                } finally {
                    if (reader != null)
                        reader.close();
                }
                List<String> Players=(List<String>) jsb.get("Players");
                for (String player : Players) {
                    System.out.println(player);
                }           
    }
}

@ Sagar Zala: ตัวอย่างที่คุณคาดหวัง ..
arun kongara

0

คุณมีสตริงเช่นนี้

"[{"id":2550,"cityName":"Langkawi","hotelName":"favehotel Cenang Beach - Langkawi","hotelId":"H1266070"},
{"id":2551,"cityName":"Kuala Lumpur","hotelName":"Metro Hotel Bukit Bintang","hotelId":"H835758"}]"

จากนั้นคุณสามารถแอบแฝงมันArrayListผ่านGsonเช่น

var hotels = Gson().fromJson(historyItem.hotels, Array<HotelInfo>::class.java).toList()

คลาสHotelInfoของคุณควรเป็นเช่นนี้

import com.squareup.moshi.Json

data class HotelInfo(

    @Json(name="cityName")
    val cityName: String? = null,

    @Json(name="id")
    val id: Int? = null,

    @Json(name="hotelId")
    val hotelId: String? = null,

    @Json(name="hotelName")
    val hotelName: String? = null
)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.