精华内容
下载资源
问答
  • Gson解析空字符串异常的处理

    Gson解析空字符串异常的处理

    参考文章:

    (1)Gson解析空字符串异常的处理

    (2)https://www.cnblogs.com/jiangzhishan/p/9318148.html


    备忘一下。


    展开全文
  • 最近在一个项目中遇到一个问题,当面对一些不规范的json,我们的gson解析经常会抛出各种异常导致app崩溃,通过在网上查找资料,找到了原因,这篇文章给大家介绍了一些可以采取的措施来避免这种情况,有需要的朋友们...
  • Gson解析List为空应如何解决

    万次阅读 2015-10-16 09:34:08
    前面是我遇到的问题,后面是解决方法 服务器端发送数据: AnliDataDao anliDao=new AnliDataDao(); List anlilist; String jsonString=""; ... anlilist = anliDao.queryAnli();... Gson gson = new Gso

    前面是我遇到的问题,后面是解决方法

    服务器端发送数据:

    <span style="font-size:18px;">AnliDataDao anliDao=new AnliDataDao();
    			List<AnliData> anlilist;
    			String jsonString="";
    			try {
    				anlilist = anliDao.queryAnli();//得到了一个Anli类的List数组 
    				Gson gson = new Gson();
    				 jsonString = gson.toJson(anlilist);
    			} catch (Exception e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    </span>
    客户端接收数据,对gson数据解析:
    <span style="font-size:18px;">ype type = new TypeToken<List<AnliData>>() {
    				}.getType();
    				Gson gson =  new Gson();
    				list = gson.fromJson(result, type);
    for(int i=0;i<list.size();i++){
    					System.out.println("------------这是HttpUtil中的Gson解析-------------------------------------\n这个是图片地址:"+list.get(i).getMyImageUrl()+"这个是文本信息\n"+list.get(i).getMyTvContent());
    				}
    </span>

    按理说,我们客户端在type中的数据类型和服务器端发送的数据类型是一样的,但是解析的结果为null;这难道是Gson解析不了List的数组?这让我头疼了许久;


    后来发现了一种更好的解决方法:


    对你所要传的数据包装在一个List类中,你怎么也是要发送一个List数组,就不如直接把你要发送的数据直接封装在一个List类中:

    import java.util.List;
    
    public class AnliDataList {
    	List<AnliData> anlilist;
    
    	public List<AnliData> getAnlilist() {
    		return anlilist;
    	}
    
    	public void setAnlilist(List<AnliData> anlilist) {
    		this.anlilist = anlilist;
    	}
    	
    	
    }


    这样一来我们直接按照这个类解析就好了:


    public class demo {
    
    	public static void main(String args[]) {
    
    		
    
    		AnliDataDao anliDao = new AnliDataDao();//这是为了从数据库中拿到数据
    		AnliDataList anlidatalist=new AnliDataList();//实例化一个对AnliData的封住类(也就是List<AnliData>)
    		String jsonString = "";
    		
    		try {
    			anlidatalist.setAnlilist(anliDao.queryTextView()); //这就用我们写的set方法,将得到的list数组放到我们的封装List类中;
    			Gson gson = new Gson();
    			jsonString = gson.toJson(anlidatalist);
    			// jsonString = createJsonString("anlitest", anlilist);
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    
    		
    		Type type = new TypeToken<AnliDataList>() {
    		}.getType();
    		Gson gson =  new Gson();
    	AnliDataList	list = gson.fromJson(jsonString, type);
    for(int i=0;i<list.getAnlilist().size();i++){
    
    //这样我们就拿到数据了;
    	System.out.println(list.getAnlilist().get(i).getMyImageUrl()+"\n"+list.getAnlilist().get(i).getMyTvContent());
    	}
    
    	}
    
    }
    



    展开全文
  • Retrofit Gson解析空字符串的问题

    万次阅读 热门讨论 2016-06-02 13:40:00
    在实际开发项目中,服务器经常会用字符串 “” 作为返回结果表示空值 ,但这在Gson当中就会遇到问题,如果这项数据的类型不是字符串,Gson解析就会报错 我们希望程序可以自动将字符串解析对应类型的空值,...

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

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

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

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

    public class IntegerDefault0Adapter implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
        @Override
        public Integer deserialize(JsonElement json, Type typeOfT, 
                                JsonDeserializationContext context) 
                                 throws JsonParseException {
            try {
                if (json.getAsString().equals("")){
                    return 0;
                }
            } catch (Exception ignore){
            }
            try {
                return json.getAsInt();
            } catch (NumberFormatException e) {
                throw new JsonSyntaxException(e);
            }
        }
    
        @Override
        public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
            return new JsonPrimitive(src);
        }
    }

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

    public static Gson buildGson() {
           if (gson == null) {
               gson = new GsonBuilder()
                       .setDateFormat("yyyy-MM-dd HH:mm:ss")
                       .registerTypeAdapter(Integer.class, new IntegerDefault0Adapter())
                       .registerTypeAdapter(int.class, new IntegerDefault0Adapter())
                       .create();
           }
           return gson;
       }

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

    Retrofit = new Retrofit.Builder()
                    .baseUrl(API_SERVER + "/")
                    //传入buildGson生成的自定义Gson
                    .addConverterFactory(GsonConverterFactory.create(buildGson()))
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(mOkHttpClient)
                    .build();

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

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

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

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

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

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

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

    /**
     * 列表解析类适配器的工厂类
     * 必须通过注解@JsonAdapter方式才能优先于默认的CollectionTypeAdapterFactory
     */
    public final class ListTypeAdapterFactory implements TypeAdapterFactory {
    
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
            Type type = typeToken.getType();
    
            Class<? super T> rawType = typeToken.getRawType();
            if (!List.class.isAssignableFrom(rawType)) {
                return null;
            }
    
            Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
            TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
    
            @SuppressWarnings({"unchecked", "rawtypes"}) // create() doesn't define a type parameter
            TypeAdapter<T> result = new Adapter(gson, elementType, elementTypeAdapter);
            return result;
        }
    
        private static final class Adapter<E> extends TypeAdapter<List<E>> {
            private final TypeAdapter<E> elementTypeAdapter;
    
            public Adapter(Gson context, Type elementType,
                           TypeAdapter<E> elementTypeAdapter) {
                this.elementTypeAdapter = new TypeAdapterRuntimeTypeWrapper<E>(
                                            context, elementTypeAdapter, elementType);
            }
    
            //关键部分是这里,重写解析方法
            public List<E> read(JsonReader in) throws IOException {
                //null值返回null
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return null;
                }
                //新建一个空的列表
                List<E> list = new ArrayList<>();
                try {
                    in.beginArray();
                    while (in.hasNext()) {
                        E instance = elementTypeAdapter.read(in);
                        list.add(instance);
                    }
                    in.endArray();
                    //正常解析成为列表
                } catch (IllegalStateException e){ //如果是空字符串,会有BEGIN_ARRAY报错
                    //此时尝试解析成字符串,如果不是空字符串,则依旧抛出异常
                    //如果是空字符串,则不抛出异常,使最终返回一个空的列表
                    if (!"".equals(in.nextString())){
                        throw e;
                    }
                }
    
                return list;
            }
    
            public void write(JsonWriter out, List<E> list) throws IOException {
                if (list == null) {
                    out.nullValue();
                    return;
                }
    
                out.beginArray();
                for (E element : list) {
                    elementTypeAdapter.write(out, element);
                }
                out.endArray();
            }
        }
    }

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

    public class UserListModel{
        @JsonAdapter(ListTypeAdapterFactory.class)
        List<UserProfileModel> users;
    }

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

    转自:http://blog.csdn.net/efan006/article/details/50544509

    展开全文
  • 什么要容错了,在javaBean中声明了int类型的age 如果服务端 返回的是"" 字符串怎么办呢?崩溃?
  • Gson解析null替换为空字符串

    千次阅读 2016-03-03 22:07:07
    json解析有很多工具,这里说的是最常用也是解析速度最快的GsonGson是google家出的,有一个缺点就是无法设置null替换, 我们只能手动的批量替换服务器返回的null了,正常的接口定义的时候是绝对
    文/hloong(简书作者)
    原文链接:http://www.jianshu.com/p/c6dd9a6b10ee
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    json解析有很多工具,这里说的是最常用也是解析速度最快的Gson,Gson是google家出的,有一个缺点就是无法设置null替换,
    我们只能手动的批量替换服务器返回的null了,正常的接口定义的时候是绝对不允许服务器返回null的,后台结果却总会出现null!
    如果搜索的话有一个常见的答案,
    Gson gson = new GsonBuilder().serializeNulls().create();
    但是这个却无法解决反序列问题,怎么解决呢?我在stackoverflow上找到了这个问题,亲测有效
    http://stackoverflow.com/questions/9483348/gson-treat-null-as-empty-string/24252578#24252578

    解决办法如下:

    Gson gson  = new GsonBuilder().registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()).create();
    //然后用上面一行写的gson来序列化和反序列化实体类type
    gson.fromJson(json, type);
    gson.toJson(type);

    //NullStringToEmptyAdapterFactory的代码

    public class NullStringToEmptyAdapterFactory<T> implements TypeAdapterFactory {
        @SuppressWarnings("unchecked")
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
            Class<T> rawType = (Class<T>) type.getRawType();
            if (rawType != String.class) {
                return null;
            }
            return (TypeAdapter<T>) new StringNullAdapter();
        }
    }

    // StringNullAdapter代码

    public class StringNullAdapter extends TypeAdapter<String> {
        @Override
        public String read(JsonReader reader) throws IOException {
            // TODO Auto-generated method stub
            if (reader.peek() == JsonToken.NULL) {
                reader.nextNull();
                return "";
            }
            return reader.nextString();
        }
        @Override
        public void write(JsonWriter writer, String value) throws IOException {
            // TODO Auto-generated method stub
            if (value == null) {
                writer.nullValue();
                return;
            }
            writer.value(value);
        }
    }
    展开全文
  • 对于一些不规范的json,使用gson解析经常会抛出各种异常导致应用功能失效甚至崩溃 解决 我们希望在接口返回的json异常时,也能解析成功,空值对应的转换默认值,如:keyId=0; 首先我们希望在数据生成时就能避免出现异常...
  • Build APKs 也可以正常运行,但是,正式打包签名后,Gson解析为null 这是混淆的问题,javabean被混淆后,无法正常解析 -dontwarn com.google.gson.** -keep class com.google.gson.** { *; } -keepattributes ...
  • GSON 解析 JSON

    2018-11-02 15:14:39
    Gson 解析 和 格式化 Gson 格式化 Gson 解析 解析assets目录下的Json文件 ## Json 介绍 Json 全称 JavaScript Object Natation ,用来描述数据结构,它是基于纯文本的数据格式,是一种轻量级的数据交换...
  • 解决办法: 将内部类定义静态类
  • 服务器用字符串 “” 作为返回结果表示空值 ,Gson解析报错 正常情况下json: { "code":0, "msg":"ok", "data":{ "name":"Sim", "age":18 } } data对应的实体bean类: public class Bean { private ...
  • 今天遇到一个问题程序打包apk之后 gson解析为null 原因是因为打包混淆出现的bug,记录一下 -keepattributes Signature -keep class sun.misc.Unsafe { *; } -keep class com.google.gson.**{*;} -keep class xxx....
  • Anroid gson解析

    2016-06-25 15:08:39
    Gson 解析 和 格式化 Gson 格式化 Gson 解析 Json 介绍 Json 全称 JavaScript Object Natation ,用来描述数据结构,它是基于纯文本的数据格式,是一种轻量级的数据交换格式。广泛应用于 服务端 与 客户端 的...
  • Gson解析

    2017-09-16 16:52:58
    Gson 是google解析Json的一个开源框架,同类的框架fastJson,JackJson等等 本人fastJson用了两年,也是从去年才开始接触Gson,希望下面的总结会对博友有用,至于Gson与FastJson的对比,其实半斤八两的问题,不再赘述 第...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,831
精华内容 2,732
关键字:

gson解析为空