Android只json数据的处理-Gson_android gson tojson 去掉最外一層括號_xh_4215的博客-程序员秘密

技术标签: 数据  Android开发进阶  android  json  Gson  

Gson的基础的使用


Gson提供了fromJson() 和toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化。同时每个方法都提供了重载方法,我常用的总共有5个

Gson.toJson(Object);
Gson.fromJson(Reader,Class);
Gson.fromJson(String,Class);
Gson.fromJson(Reader,Type);
Gson.fromJson(String,Type);

基本数据类型的转化:

       Gson gson = new Gson();
//        解析
        int i = gson.fromJson("100", int.class);
        Log.d(TAG, "解析int数据: " + i);
        boolean t = gson.fromJson("true", boolean.class);
        Log.d(TAG, "解析boolean数据 " + t);
        double d = gson.fromJson("33.44", double.class);
        Log.d(TAG, "解析double数据 " + d);
        String s = gson.fromJson("String", String.class);
        Log.d(TAG, "解析String类型的数据" + s);
//        生成
        String i1 = gson.toJson(100);
        Log.d(TAG, "生成int数据: " + i1);
        String t1 = gson.toJson(false);
        Log.d(TAG, "生成boolean数据: " + t1);
        String s1 = gson.toJson("9264264");
        Log.d(TAG, "生成string数据: " + s1);
        String d1 = gson.toJson(33.33);
        Log.d(TAG, "生成double数据: " + d1);

在看别人的博客学习的时候说这个double转化的时候有猫腻但是我没发现 ,这样做的demo是能正常的转换的。

java数据对象的序列化和反序列化

 public String myJsonObject = "{\"user_name\":\"小黑黑\",\"user_password\":\"luanguiming\",\"age\":26}";
    String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";
  Gson gson = new Gson();
//        json数据转化为对象
        UserBean userBean1 = gson.fromJson(myJsonObject, UserBean.class);
        Log.d(TAG, "数据对象为" + userBean1.getUsername() + userBean1.getUserpassword() + userBean1.getAge());
//         转化json数组
        String[] StringArray = gson.fromJson(jsonArray, String[].class);
        Log.d(TAG, "转化的数组为" + StringArray[0]);
//        转化jsn数据为集合
        List<String> jsonList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {
        }.getType());
        Log.d(TAG, "转化的集合为" + jsonList.get(2));

以上是将一个json字符串反序列化为 对象 ,数组,集合的代码

 Gson gson = new Gson();
//        javaBean 转化为json数据
        UserBean userBean = new UserBean("xiaohei", "luanguiming123", 24, new Date());
        String jsonObject = gson.toJson(userBean);
        Log.d(TAG, "将javaBean转化为json串 " + jsonObject);
//        数组对象转化为json
        String arrayjson = gson.toJson(arrays);
        Log.d(TAG, "将数组对象转化为json串 " + arrayjson);
//          list对象转化为json
        String listjson = gson.toJson(list);
        Log.d(TAG, "将集合对象转化为json串 " + listjson);

以上的代码是将javaBean对象,字符串数组,list集合序列化为json字符串

属性重命名的注解

  @SerializedName("user_name")
    public String username;
    @SerializedName("user_password")
    public String userpassword;

通过SerializedName注解将字段设置为转化为json字符串对应的字段名称,

@SerializedName(value = "emailAddress", alternate = {
   "email", "email_address"})
public String emailAddress;

通过alternate 实现当上面的三个属性(email_address、email、emailAddress)都中出现任意一个时均可以得到正确的结果。
注:当多种情况同时出时,以最后一个出现的值为准。

字段的映射

  • 默认的映射的设置
        Gson gson2 = new GsonBuilder()                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
                .create();
        String sss = gson2.toJson(userBean);
        Log.d(TAG, "借助gsonbuilder实现字段的格式的变化 " + sss);

通过setFieldNamingPolicy()方法实现 内部存放的是以定义好的实体的类型
实体的具体的对应的映射方式

FieldNamingPolicy   结果(仅输出emailAddress字段)
IDENTITY    {
   "emailAddress":"ikidou@example.com"}
LOWER_CASE_WITH_DASHES  {
   "email-address":"ikidou@example.com"}
LOWER_CASE_WITH_UNDERSCORES {
   "email_address":"ikidou@example.com"}
UPPER_CAMEL_CASE    {
   "EmailAddress":"ikidou@example.com"}
UPPER_CAMEL_CASE_WITH_SPACES    {
   "Email Address":"ikidou@example.com"
  • 自定义映射的设置
  Gson gson2 = new GsonBuilder()
//                此处可以创建
                .setFieldNamingStrategy(new FieldNamingStrategy() {
                    @Override
                    public String translateName(Field field) {
//                       内部实现字符串的自定义的格式
                        return null;
                    }
                })
                .create();
        String sss = gson2.toJson(userBean);
        Log.d(TAG, "借助gsonbuilder实现字段的格式的变化 " + sss);
        通过使用setFieldNamingStrategy()通过内部的方法自己定义映射的规则。

Gson实现流式序列化和反序列化

  • 自动序列化
Gson提供了fromJson()toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化。同时每个方法都提供了重载方法,我常用的总共有5个。
  • 手动反序列化
//        通过jsonReader解析将json数据转化为一个对象
        JsonReader reader = new JsonReader(new StringReader(myJsonObject));
        UserBean bean = new UserBean();
        try {
            reader.beginObject();
            while (reader.hasNext()) {
                String s = reader.nextName();
                switch (s) {
                    case "user_name":
                        bean.username = reader.nextString();
                        break;
                    case "user_password":
                        bean.userpassword = reader.nextString();
                        break;
                    case "age":
                        bean.age = reader.nextInt();
                        break;
                }

            }
            reader.endObject();
            Log.d(TAG, "解析的数据为" + bean.getAge() + bean.getUserpassword() + bean.getUsername());

        } catch (Exception e) {
            e.printStackTrace();
        }

流式反序列化就是通过一个流读取json字符串之后通过jsonReader将他反序列化为一个数据对象。

  • 手动序列化
//   通过jsonWriter将对象转化为json
        UserBean bean1 = new UserBean("小黑", "小黑是程序员", 12, new Date());
        JsonWriter jsonWriter = new JsonWriter(new OutputStreamWriter(System.out));
        try {
            jsonWriter.beginObject()
                    .name("username")
                    .name("password")
                    .name("age");
            jsonWriter.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

流式序列化就是通过jsonWriter将对象序列化到一个流中通过流中读取数据。

通过GsonBuilder 输出null ,和格式化输出时间

  • 创建GsonBuilder对象
 Gson gson2 = new GsonBuilder()
  .create();
  • 调用对应的方法实现对应的功能`
  Gson gson = new GsonBuilder()
                .serializeNulls()//输出对象中的空的数值
                .create();

备注 默认的情况下序列化的对象没有赋值的字段是不输出的通过
.serializeNulls()空的值也会输出。

 Gson gson = new GsonBuilder()
                // 在序列化和反序化时均生效
                .setDateFormat("yyyy-MM-dd")
                .create();

备注:将时间字段按一定的格式输出

 Gson gson = new GsonBuilder()

//                //格式化输出
                .setPrettyPrinting()
                .create();

备注:格式化输出json字符串

几种过滤指定的字段的讲解

  • 通过@Expose注释指定过滤掉的字段
    @Expose
    public int id;
    @Expose
    public String name;

这样在对javaBean序列化的时候id,name这两个字段会被忽略掉。

  • 基于版本的过滤字段
//    设置version version的值小于4的时候输出的数值
    @Since(4)
    public String name;
//    设置version version的值大于5的时候输出的数值
    @Until(5)
    public String age;
       Gson gson1 = new GsonBuilder()
                .setVersion(3)
                .create();
        String student = gson1.toJson(studentBean);
        Log.d(TAG, "数据转化" + student);

Gson在对基于版本的字段导出提供了两个注解 @Since 和 @Until,和GsonBuilder.setVersion(Double)配合使用。@Since 和 @Until都接收一个Double值。
使用方法:当前版本(GsonBuilder中设置的版本) 大于等于Since的值时该字段导出,小于Until的值时该该字段导出。

  • 基于访问修饰符的字段过滤
  StudentBean studentBean1 = new StudentBean();
        studentBean.setAge("15");
        studentBean.setGender(1);
        studentBean.setName("宅雨声");
        test modifierSample = new test();
        Gson gson2 = new GsonBuilder()
//                 排除指定的权限的字段
                .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PRIVATE)
                .create();
        String studentBean2 = gson2.toJson(modifierSample);
        Log.d(TAG, "通过访问的权限设置序列化的数据" + studentBean2);

通过excludeFieldsWithModifiers()方法设置过滤的的访问的权限的名称。

  • 自定义过滤规则
  XhBean bean1 = new XhBean();
        bean1.setAge(12);
        bean1.setDescription("android程序员");
        bean1.setGender("男");
        bean1.setName("栾桂明");
        Gson gson3 = new GsonBuilder()
                .addSerializationExclusionStrategy(new ExclusionStrategy() {
                    @Override
                    public boolean shouldSkipField(FieldAttributes fieldAttributes) {
                        // 这里作判断,决定要不要排除该字段,return true为排除 这里是排除指定名称的字段
                        if ("name".equals(fieldAttributes.getName()))
                            return true;
                        Expose expose = fieldAttributes.getAnnotation(Expose.class);
                        if ((expose != null && expose.deserialize() == false))
                            return true;
                        return false;
                    }

                    @Override
                    public boolean shouldSkipClass(Class<?> aClass) {
                        // 直接排除某个类 ,return true为排除  这里实现的是排除指定的类型的数据
                        return (aClass == int.class || aClass == Integer.class);
                    }
                }).create();
        String xhjson = gson3.toJson(bean1);
        Log.d(TAG, "自定义的输出设置" + xhjson);

通过addSerializationExclusionStrategy()来实现 shouldSkipClass方法设置被过滤调的数据的数据类型
shouldSkipField设置具体的过滤的细节如以上实现的是通过字段的名称过滤。

使用TypeAdapter实现序列化和反序列化有点序列和反序列化的具体的细节可以控制

 XhBean bean1 = new XhBean();
        bean1.setAge(12);
        bean1.setDescription("android程序员");
        bean1.setGender("男");
        bean1.setName("栾桂明");
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(XhBean.class,new UserTypeAdapter())
                .create();
        System.out.println(gson.toJson(bean1));
        UserBean bean =  gson.fromJson(myJsonObject, UserBean.class);
        System.out.println(bean.age+bean.userpassword+bean.username);
public class UserTypeAdapter extends TypeAdapter<XhBean> {
    
    //    write  -> outputstream -> 将数据写入到输出流中输出
    @Override
    public void write(JsonWriter jsonWriter, XhBean xhBean) throws IOException {
//        把数据写入到流中输出
        jsonWriter.beginObject();
        jsonWriter.name("name").value(xhBean.name);
        jsonWriter.name("gender").value(xhBean.gender);
        jsonWriter.name("age").value(xhBean.age);
        jsonWriter.name("description").value(xhBean.description);
        jsonWriter.endObject();
    }

    //  read -> inoutstream -> 从输入流中读取数据
    @Override
    public XhBean read(JsonReader jsonReader) throws IOException {
        //       从流中读取数据
        XhBean user = new XhBean();
        jsonReader.beginObject();
        while (jsonReader.hasNext()) {
            switch (jsonReader.nextName()) {
                case "name":
                    user.name = jsonReader.nextString();
                    break;
                case "age":
                    user.age = jsonReader.nextInt();
                    break;
                case "gender":
                    user.gender = jsonReader.nextString();
                    break;
                case "description":
                    user.description = jsonReader.nextString();
                    break;

            }
        }
        jsonReader.endObject();
        return user;
    }
}

创建一个类继承TypeAdapter实现具体的序列化和反序列化
通过创建GsonBuilder的registerTypeAdapter()使用自定义的Adapter。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xh_ssh/article/details/78873602

智能推荐

你必须掌握的 21 个 Java 核心技术!(干货)_Java笔记虾的博客-程序员秘密

来源:java进阶架构师1. JVM相关2. Java的运行3. 数据类型4. 对象和实例5. 访问控制6. 流程控制7. 面向对象编程的概念8. static9. 基础知识点10. 集...

【kubernetes/k8s源码分析】kubectl-controller-manager之HPA源码分析_张忠琳的博客-程序员秘密

本文基于kubernetes版本:v1.12.1HPA介绍 https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ The Horizontal Pod Autoscaler automatically scales the number of pods in a replica...

vue实现扫描条码_quaggajs vue_榴莲豆包的博客-程序员秘密

首先npm下载vue-quaggajs这个依赖。下边是扫描页面&lt;template&gt; &lt;div&gt; &lt;v-header title="扫一扫"/&gt; &lt;v-quagga :onDetected="logIt" :readerSize="readerSize" :readerTypes="['ean_reader']"&gt;&lt;/v-quagga&gt; &lt;/div&gt;&lt;/template&gt;&lt;scri

自旋锁是什么_轻量级锁自旋是什么?_ScilogyHunter的博客-程序员秘密

概述spinlock又称自旋锁,是实现保护共享资源而提出的一种轻量级锁机制。自旋锁与互斥锁比较类似,都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个持有者,即只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,而是一直循环在那里看是否该自旋锁的持有者已经释放了锁,"自旋"一词就是因此而得名。锁一旦被释放,就会被等待的线程立即获取,而不需要经过唤醒和上下文切换。适用情况自

jquery 基础知识学习.入门级教程_lazypen555的博客-程序员秘密

基础知识在深入研究有趣的 jQuery 内容之前,我们先了解一些基础知识 — 如何安装 jQuery,以及如何使其正常运行等。首先从 下载 小节下载 jQuery 库,然后像链接其他外部 JavaScript 文件一样链接到该库:清单 1. 如何在代码中安装 jQuery // Correct$(document).ready(function(){ $("div").addClass("a"); });// - or -$(docum

随便推点

Unity实现对电脑文件夹和文件的重命名方法_unity怎么改文件夹名字_周周的Unity小屋的博客-程序员秘密

项目中有导出文件或文件夹功能需求时,类似Unity导出包或打包exe一样,都要让用户选择路径,并输入指定名称,将导出的文件或文件夹命名为用户输入的名称。刚开始我想到的方法是使用System.IO命名空间下的File类的Move方法或FileInfo类的MoveTo方法来实现,但实践发现并不通用,我找到了一种在Unity中更实用的重命名文件夹和文件的方法,可直接对指定路径下的文件夹或文件重命名。本博客将演示用windows的库Microsoft.VisualBasic.Dll实现对电脑文件夹和文件的重命名方法

百度地图AndroidSDK:定位、画区域、线路规划、搜索_芒果蜜桃π的博客-程序员秘密

参考学习: 百度地图官网: androidsdk/guide/basicmap - Wiki http://lbsyun.baidu.com/index.php?title=androidsdk/guide/basicmap 很有学习价值!!! Small_Cake的专栏里对于百度地图的使用做了很详细的介绍 1.深入学习百度地图Android SDK v4.0.0【第一关】基础地图 - ...

前端学习之路css(01)-简介_戚继光的博客-程序员秘密

CSS 简介1. CSS是什么CSS 指层叠样式表 (Cascading Style Sheets);样式定义如何显示 HTML 元素;样式通常存储在样式表中;把样式添加到 HTML 4.0 中,是为了解决内容与表现分离的问题;外部样式表可以极大提高工作效率;外部样式表通常存储在 CSS 文件中;多个样式定义可层叠为一。2. CSS的存在意义它解决了样式和内容分离的问题,使开发更加

DLV调试_vali-sweet的博客-程序员秘密

DLV调试:kubectl exec进入容器dlv的位置在 /var/log/vali下./dlv attach 8 对进程号为8的进程进行 DLV调试b /proj-workspace/portal/restful/module/sts/get.go:320 在某一行加断点,注意文件路径是相对路径c 继续此处需要调用一下接口args 查看所有参数n 下一行print statefulSet 打印变量...

SpringBoot 异步事件实现异步(ApplicationEventPublisher、ApplicationEvent)_gu_zhou的博客-程序员秘密

SpringBoot 异步事件实现异步(ApplicationEventPublisher、ApplicationEvent)​ 当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对应的处理方法。实现步骤:自定义发布的事件类,需要继承 ApplicationEvent 或者PayloadApplicationEvent(该类也仅仅是对A...

为创建的一个自定义数据类型进行运算符重载_public int getgys(intx,inty) 插装_yanerhao的博客-程序员秘密

在前面一篇文章里谈到编程语言里面只有Int,float,double等基本数据类型,而没有有理数类型,因此我们自定义了一个Rational类型(见http://blog.csdn.net/yanerhao/article/details/45009283),表示有理数,含有四则运算,比较,输出结果等成员函数,但是与常见的基本类型相比,还是显得特殊,显得格格不入。需要进一步基本化,这就是需要运算符重

推荐文章

热门文章

相关标签