Retrofit Gson解析空字符串的问题

来源:互联网 发布:ios降级会丢失数据吗 编辑:程序博客网 时间:2024/05/21 10:04

在实际开发项目中,服务器经常会用空字符串 “” 作为返回结果表示空值 ,但这在Gson当中就会遇到问题,如果这项数据的类型不是字符串,Gson解析就会报错 
我们希望程序可以自动将空字符串解析为对应类型的空值,比如整型就解析为0,List型就解析为一个Empty List

这个问题可以说是我用Retrofit+Gson以来最大的一个坑,以至于我在研究时差不多都要把源码看完了

提一件离奇的事是,Gson在用整型解析空字符串时,报的居然是”Inavalid double”的错误 
经过研究源码后发现,Gson会优先尝试解析为整型,解析失败并不会报错误, 
继续尝试解析为double型,再失败才会报错,所以得到了”Inavalid double”

解决方案: 
针对整型的解析,先写一个解析适配器,实现JsonSerializer, JsonDeserializer 
重写解析方法,先尝试用String类型解析,如果等于空字符串”“,则返回0值 
否则再尝试用整型解析,并且catch数字格式异常转成Json解析异常抛出

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">IntegerDefault0Adapter</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">JsonSerializer</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Integer</span>>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">JsonDeserializer</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Integer</span>> {</span>    @Override    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Integer deserialize(JsonElement json, Type typeOfT,                             JsonDeserializationContext context)                              throws JsonParseException {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (json.getAsString().equals(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)){                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;            }        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Exception</span> ignore){        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> json.getAsInt();        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (NumberFormatException e) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> JsonSyntaxException(e);        }    }    @Override    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> JsonPrimitive(src);    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>

然后在GsonBuilder里注册适配器到类型Integer与类型int

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> Gson <span class="hljs-title" style="box-sizing: border-box;">buildGson</span>() {       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (gson == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {           gson = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> GsonBuilder()                   .setDateFormat(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"yyyy-MM-dd HH:mm:ss"</span>)                   .registerTypeAdapter(Integer.class, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IntegerDefault0Adapter())                   .registerTypeAdapter(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>.class, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IntegerDefault0Adapter())                   .create();       }       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> gson;   }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

再在构建Retrofit时用这个自定义的Gson替换掉原生的

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Retrofit = new Retrofit<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Builder</span>()                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.baseUrl</span>(API_SERVER + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/"</span>)                //传入buildGson生成的自定义Gson                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addConverterFactory</span>(ResponseConverterFactory<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.create</span>(buildGson()))                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addCallAdapterFactory</span>(RxJavaCallAdapterFactory<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.create</span>())                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.client</span>(mOkHttpClient)                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.build</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

这样Gson在遇到整型解析时可以将空字符串解析为0了

然后我打算用同样的方式解决List的解析问题,但没想到情况没有这么简单。

因为List并不像整形一样是一个基本类型,List本身在数据解析的时候是要带泛型的 
我不可能在构建的时候就定好集合里的数据类型。

而如果不定泛型里的数据类型,重写适配器就得根据运行时遇到的类型分别进行操作,这无异于把Gson的工作重新做一遍。

经过研究源码后发现Gson对待List也并非当做一个类型去解析的 
而是在初始化时带有一个CollectionTypeAdapterFactory,在遇到JsonArray类型的数据就会调用集合类型的解析器,然后再适配集合里的对应数据类型。总之一句话就是,挺复杂,并且不怎么能扩展。

经过研究后我找到的解决方案是:

通过注解方式@JsonAdapter可以指定对应的适配器,优先级是高于默认的CollectionTypeAdapterFactory,和通过GsonBuilder传入的适配器的。 
然后还是拷贝CollectionTypeAdapterFactory出来,改一份ListTypeAdapterFactory出来

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 列表解析类适配器的工厂类 * 必须通过注解@JsonAdapter方式才能优先于默认的CollectionTypeAdapterFactory */</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> ListTypeAdapterFactory implements TypeAdapterFactory {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <T> TypeAdapter<T> <span class="hljs-title" style="box-sizing: border-box;">create</span>(Gson gson, TypeToken<T> typeToken) {        Type type = typeToken.getType();        Class<? super T> rawType = typeToken.getRawType();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!List.class.isAssignableFrom(rawType)) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;        }        Type elementType = $Gson$Types.getCollectionElementType(type, rawType);        TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>(elementType));        @SuppressWarnings({<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"unchecked"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"rawtypes"</span>}) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// create() doesn't define a type parameter</span>        TypeAdapter<T> result = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Adapter(gson, elementType, elementTypeAdapter);        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> final <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> Adapter<E> extends TypeAdapter<List<E>> {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> final TypeAdapter<E> elementTypeAdapter;        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">Adapter</span>(Gson context, Type elementType,                       TypeAdapter<E> elementTypeAdapter) {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.elementTypeAdapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TypeAdapterRuntimeTypeWrapper<E>(                                        context, elementTypeAdapter, elementType);        }        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//关键部分是这里,重写解析方法</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> List<E> <span class="hljs-title" style="box-sizing: border-box;">read</span>(JsonReader <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>) throws IOException {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//null值返回null</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>.peek() == JsonToken.NULL) {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>.nextNull();                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;            }            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//新建一个空的列表</span>            List<E> list = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<>();            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>.beginArray();                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>.hasNext()) {                    E instance = elementTypeAdapter.read(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>);                    list.add(instance);                }                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>.endArray();                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//正常解析成为列表</span>            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IllegalStateException e){ <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果是空字符串,会有BEGIN_ARRAY报错</span>                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此时尝试解析成字符串,如果不是空字符串,则依旧抛出异常</span>                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果是空字符串,则不抛出异常,使最终返回一个空的列表</span>                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>.equals(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>.nextString())){                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> e;                }            }            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> list;        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">write</span>(JsonWriter <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>, List<E> list) throws IOException {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (list == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.nullValue();                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;            }            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.beginArray();            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (E element : list) {                elementTypeAdapter.write(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>, element);            }            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.endArray();        }    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li></ul>

最后就是Model类里面注解指定

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> UserListModel{    @JsonAdapter(ListTypeAdapterFactory.class)    List<UserProfileModel> users;}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

这样Gson就能将空字符串解析成为空列表了

0 0
原创粉丝点击