简体   繁体   English

将字符串转换为 ArrayList<string> 使用 GSON</string>

[英]Convert String to ArrayList<String> using GSON

I am trying to deserialize a JSON data to a POJO.我正在尝试将 JSON 数据反序列化为 POJO。

The issue is that the list object is coming as a string, and gson gives an IllegalStateExceptioState.问题是列表 object 以字符串形式出现,而 gson 给出了 IllegalStateExceptioState。 How can I parse the string as a list to an ArrayList using gson?如何使用 gson 将字符串解析为 ArrayList 的列表?

JSON DATA 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: 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);   
        }
    }

Deserialization:反序列化:

EventData eventData = EventData.builder(json);

While deserializing i get the following error反序列化时出现以下错误

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

Boxing structured data in a string where it is unnecessary is a very common design issue across different serialization approaches.在不需要的地方将结构化数据装箱是跨不同序列化方法的一个非常常见的设计问题。 Fortunately, Gson can deal with fields like owner_emails (but not message of course).幸运的是,Gson 可以处理诸如owner_emails之类的字段(当然不能处理message )。

Merely create a type adapter factory than can create a type adapter for a particular type by substituting the original one and doing a bit of more work.仅仅创建一个类型适配器工厂,而不是通过替换原始类型并做更多工作来为特定类型创建类型适配器。 The adapter is supposed to read the payload as string and delegate the string deserialization to the type adapter it substitutes.适配器应该将有效负载作为字符串读取,并将字符串反序列化委托给它所替代的类型适配器。

public final class JsonStringBoxTypeAdapterFactory
        implements TypeAdapterFactory {

    private JsonStringBoxTypeAdapterFactory() {
    }

    @Override
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
        final TypeAdapter<T> adapter = gson.getAdapter(typeToken);
        return new TypeAdapter<T>() {
            @Override
            public void write(final JsonWriter out, final T value) {
                throw new UnsupportedOperationException(); // TODO
            }

            @Override
            public T read(final JsonReader in)
                    throws IOException {
                return adapter.fromJson(in.nextString());
            }
        };
    }

}
@AllArgsConstructor
@ToString
@EqualsAndHashCode
final class EventData {

    @SerializedName("owner_emails")
    @JsonAdapter(JsonStringBoxTypeAdapterFactory.class)
    List<String> ownerEmails;

}

The unit test below will be green:下面的单元测试将是绿色的:

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

That's it.而已。

"owner_emails" is curently a string as follows “owner_emails”目前是一个字符串,如下所示

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

It should be它应该是

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

to be considered as array.被视为数组。 You can manually remove the quotes and parse it.您可以手动删除引号并对其进行解析。

Or you can parse it using JsonElement in Gson或者您可以使用JsonElement中的 JsonElement 对其进行解析

You can use ObjectMapper from jackson librar y for this conversion.您可以使用jackson 库中的 ObjectMapper 进行此转换。

Sample code of conversion::转换示例代码::

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

Modify the model for a list like::将 model 修改为如下列表

 public class Reportdata{
   
   private List<String> owner_emails = new ArrayList(); 

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

In addition to this, while creating the ObjectMapper object you can pass or register the module/ your custom module for deserialization in object like below.除此之外,在创建 ObjectMapper object 时,您可以传递或注册模块/您的自定义模块以在 object 中进行反序列化,如下所示。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM