使用GSON将字符串转换为数组列表< String>

v2g6jxz6  于 2022-11-06  发布在  其他
关注(0)|答案(3)|浏览(256)

我正在尝试将JSON数据反序列化为POJO。
问题是列表对象是以字符串的形式出现的,而gson给出了一个IllegalStateExceptioState。我如何使用gson将字符串解析为一个ArrayList?

JSON数据

{
   "report_id":1943,
   "history_id":3302654,
   "project_id":null,
   "owner_emails":"[\"abcd@xyz.com\"]",
   "message":"Array\n(\n    [name] => SOMENAME\n    [age] => 36\n    [gender] => male\n)\n"
}

POJO:

public class EventData {

        private static Gson gson = new Gson();

        @SerializedName("report_id")
        public String reportID;

        @SerializedName("history_id")
        public String historyID;

        @SerializedName("project_id")
        public String projectID;

        @SerializedName("owner_emails")
        public ArrayList<String> ownerEmails = new ArrayList<String>();

        @SerializedName("message")
        public String message;

        @SerializedName("title")
        public String title;

        public CrawlerNotifiedEventData(){
            this.projectID = "Undefined";
            this.reportID = "Undefined";
            this.historyID = "Undefined";
            this.title = "";
        }

        public String toJson(boolean base64Encode) throws java.io.UnsupportedEncodingException{

            String json = gson.toJson(this, CrawlerNotifiedEventData.class);

            if(base64Encode)
                return Base64.getEncoder().encodeToString(json.getBytes("UTF8"));

            return json;
        }

        public String toJson() throws java.io.UnsupportedEncodingException{
            return this.toJson(false);
        }

        public static EventData builder(String json){
            return gson.fromJson(json, EventData.class);   
        }
    }

反序列化:

EventData eventData = EventData.builder(json);

在反序列化时,我得到以下错误

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 252 path $.owner_emails
polkgigr

polkgigr1#

将结构化数据装箱到字符串中是不同序列化方法中非常常见的设计问题。幸运的是,Gson可以处理像owner_emails这样的字段(当然不能处理message)。
只需创建一个类型适配器工厂,就可以通过替换原始工厂并做更多的工作来为特定类型创建类型适配器。适配器应该将有效负载作为字符串读取,并将字符串反序列化委托给它所替换的类型适配器。
第一个
下面的单元测试将为绿色:

final EventData eventData = gson.fromJson(json, EventData.class);
Assertions.assertEquals(new EventData(ImmutableList.of("abcd@xyz.com")), eventData);

就这样了。

aij0ehis

aij0ehis2#

“owner_emails”当前是一个字符串,如下所示

"owner_emails":"[\"abcd@xyz.com\"]"

应该是

"owner_emails": ["abcd@xyz.com"]

被视为数组。您可以手动移除引号并剖析它。
或者,您可以使用Gson中的JsonElement来解析它

ycggw6v2

ycggw6v23#

您可以使用Jacksonlibrary中的ObjectMapper进行此转换。
转换示例代码:

public <T> T mapResource(Object resource, Class<T> clazz) {
        try {
            return objectMapper.readValue(objectMapper.writeValueAsString(resource), clazz);
        } catch (IOException ex) {
            throw new Exception();
        }
    }

修改list的模型,如::

public class Reportdata{

   private List<String> owner_emails = new ArrayList(); 

   @JsonDeserialize(contentAs = CustomClass.class)
   private List<CustomClass> customClassList =  new ArrayList();  
   ....// setter and getter
}

除此之外,在创建ObjectMapper对象时,您可以传递或注册模块/自定义模块,以便在对象中进行反序列化,如下所示。

objectMapper.setDefaultPropertyInclusion(Include.NON_EMPTY);
objectMapper.disable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
objectMapper.registerModule(new JavaTimeModule());

相关问题