如何使用GSON库将自由文本转换为Java中的Json字符串数组?

3

我有一个可用的自由文本文件。

当我把它转换成JSON字符串数组时,遇到了困难。

列名是可变的,可以是任意数量的列。

email_from,email_to,DATE_CHANGED

samwilliams@gmail.com, mike_haley@gmail.com, 1447666867

smithpaul@gmail.com, angierussell@gmail.com, 1447668867

第一行是表头,其余所有行都是它们的值。因此,每行都将包含与每个列相对应的相同数量的参数。列用逗号分隔。

JSON字符串响应应该像这样:

{
 "data": [
    {
        "email_from": "samwilliams@gmail.com",
        "email_to": "mike_haley@gmail.com",
        "DATE_CHANGED": "1447666867"
    },
    {
        "email_from": "smithpaul@gmail.com",
        "email_to": "angierussell@gmail.com",
        "DATE_CHANGED": "1447668867"
    }
 ]
}

此外,列可以是不同的,并且可以有“n”个。 - Angie Russell
如果你需要特定的GSON库,为什么在问题中不明确提出呢? - Andreas
3个回答

2
以下代码打开一个以逗号分隔的字符串文件,并使用while循环构建JsonObject,然后将它们添加到JsonArray中,最后打印出来(如果您希望使代码执行更好,也可以添加验证并将大部分代码移出try块)。它解决了文件中需要有n个列的需求。
package gjson;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class GJSONTest {
    public static void main(String[] args) {

        // create an array called datasets
        JsonArray datasets = new JsonArray();

        File file = new File("C:\\test_stackoverflow\\list.txt");

        try (BufferedReader br = new BufferedReader(new FileReader(file)))  {
            String line;
            boolean flag = true; 
            List<String> columns = null; 
            while ((line = br.readLine()) != null) {
               if (flag) {
                   flag = false; 
                   //process header 
                   columns = Arrays.asList(line.split(","));
               } else {
                   //to store the object temporarily
                   JsonObject obj = new JsonObject(); 
                   List<String> chunks = Arrays.asList(line.split(","));

                   for(int i = 0; i < columns.size(); i++) {
                       obj.addProperty(columns.get(i), chunks.get(i));
                   }
                   datasets.add(obj); 
               } 
            }
        } catch(FileNotFoundException fnfe) {
            System.out.println("File not found.");
        } catch(IOException io) {
            System.out.println("Cannot read file.");
        }

        Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
        System.out.println(gson.toJson(datasets));
    }
}

请看以下截图(下方有3列)。

enter image description here

在文本文件中添加了另一列,以下是输出结果。

enter image description here

这是包含您数据的示例 .txt 文件。

enter image description here


1
是的,它完美地工作了。谢谢 :) 我也尝试了以下代码。它也起作用了。 - Angie Russell
很好!你有几个选择可以选择。 - Raf

2
private String getParsedData(String data){

    String[] lines = data.split("\\r?\\n");

    List<Map> dataList = new ArrayList<Map>();


    int colCount = 0;

    if(lines.length > 1){

        String keyLine = lines[0];

        String[] keys = keyLine.split(",");

        for(int i = 1; i < lines.length; i++){

            colCount = 0;
            Map<String, Object> rawObj = new HashMap<String, Object>();

            try {

                String[] values = lines[i].split(",");

                for(String value: values){

                    rawObj.put(keys[colCount], value);
                    colCount++;
                }   

            } catch (Exception e) {

            }

            dataList.add(rawObj);
        }
    }


    Map<String, Object> rawObj = new HashMap<String, Object>();
    rawObj.put("data", dataList);
    Gson gson = new Gson();

    String res = gson.toJson(rawObj);

    return res;
}

String data = "email_from,email_to,DATE_CHANGED\r\nsamwilliams@gmail.com, mike_haley@gmail.com, 1447666867\r\nsmithpaul@gmail.com, angierussell@gmail.com, 1447668867";

但我不确定这是否是有效的代码。


我在我的答案中使用try/catch块的原因是因为我假设您正在从文件中读取数据,但是在这个答案中我不认为需要try/catch块,所以您可以将其删除。我决定使用泛型(列表和哈希映射),但是后来我注意到我可以在不使用它们的情况下完成任务,因此我的答案如此。如果没有错误,使用列表和哈希映射完成任务时应该会有性能差异,但是性能差异可能很小,难以观察或产生影响。 - Raf

1

Try this code:

public class ContactObject {
    private String emailFrom;
    private String emailTo;
    private String dateChanged;

    public ContactObject(String emailFrom, String emailTo, String dateChanged) {
        this.emailFrom = emailFrom;
        this.emailTo = emailTo;
        this.dateChanged = dateChanged;
    }

    @Override
    public String toString() {
        return "{email_from:" + emailFrom + ", email_to:" + emailTo + ", DATE_CHANGED:" + dateChanged;
    }
}

public class ContactJSON {
    private List<ContactObject> data;

    public ContactJSON(List<ContactObject> contactList) {
        this.data = contactList;
    }
}

然后在您的main()方法中,您可以使用这些类:

public static void main(String[] args) {
    List<ContactObject> contactList = new ArrayList<ContactObject>();
    ContactObject obj1 = new ContactObject("samwilliams@gmail.com", "mike_haley@gmail.com", "1447666867");
    ContactObject obj2 = new ContactObject("smithpaul@gmail.com", "angierussell@gmail.com", "1447668867");
    contactList.add(obj1);
    contactList.add(obj2);

    Gson gson = new Gson();
    String json = gson.toJson(new ContactJSON(contactList));
    System.out.println(json);
}

输出:

{"data":[{"emailFrom":"samwilliams@gmail.com","emailTo":"mike_haley@gmail.com","dateChanged":"1447666867"},{"emailFrom":"smithpaul@gmail.com","emailTo":"angierussell@gmail.com","dateChanged":"1447668867"}]}

嗨,Tim,感谢你提供的代码,它可以工作,但问题在于列名不是固定的。它可能会变化,数量也可能是n个。因此,我被卡住了,无法创建动态脚本来处理运行时的列名。 - Angie Russell
我不是完全确定你的意思。你能否更新你的问题以反映这一点? - Tim Biegeleisen
在上面的问题中,我提到了“列名是可变的,可以有n个列”。这意味着您可以拥有任何列名,因此我们无法创建用于将其序列化为json的POJO类。 - Angie Russell
因此,在运行时,电子邮件发送方(email_from)、电子邮件接收方(email_to)和日期更改(DATE_CHANGED)列名可能会有所变化,我们需要以这种方式处理它。 - Angie Russell
为什么不使用列表来处理任意数量的项目? - Tim Biegeleisen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接