精华内容
下载资源
问答
  • Google Gson用法详解

    千次阅读 2020-05-31 16:38:19
    Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。

    文章目录


    一、简介

    Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。

    Gson官网:gson
    Gson源码地址:google/gson


    二、依赖

    使用Maven导入依赖:

        <dependency>
          <groupId>com.google.code.gson</groupId>
          <artifactId>gson</artifactId>
          <version>2.8.5</version>
        </dependency>
    

    Gradle导入依赖:

    compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
    

    三、基本用法


    1、创建Gson实例

    使用Gson的第一步是创建一个Gson对象,创建爱你Gson对象有两种方式:

    • 使用 new Gson()
    • 创建GsonBuilder实例,使用 create() 方法

    1.1、new Gson()

    示例如下:

    Gson gson = new Gson();
    

    1.2、GsonBuilder.build()

    示例如下:

    GsonBuilder builder = new GsonBuilder();
    Gson gson = builder.create();
    

    2、Java对象–>JSON

    下面会用到这个实体类:

    public class Employee {
    	private int id;
    	private String firstName;
    	private String lastName;
    	private String email;
    	//省略getter/setter,构造方法,toSting方法
    }
    

    在Gson中的序列化即将Java对象转换为其JSON表示形式。 为了进行序列化,首先需要一个Gson对象,该对象可以处理转换。 接下来,需要调用函数toJson()方法并传入Employee对象。

    		Employee emp = new Employee(1001, "Lokesh", "Gupta", "howtodoinjava@gmail.com");
    		
    		Gson gson = new Gson();
    		
    		String jsonString = gson.toJson(emp);
    		
    		System.out.println(jsonString);
    

    运行结果:

    在这里插入图片描述


    3、JSON–>Java对象

    在Gson进行反序列指的是将JSON字符串转换为Java对象。 为了进行反序列化,我们需要使用Gson对象调用fromJson()函数,并在解析完成后传递两个参数,即JSON字符串和所需的Java类型。

    		String jsonString = "{'id':1001, 'firstName':'Lokesh', 'lastName':'Gupta', 'email':'howtodoinjava@gmail.com'}";
            
    		Gson gson = new Gson();
    		 
    		Employee empObject = gson.fromJson(jsonString, Employee.class);
    		 
    		System.out.println(empObject);
    

    运行结果:
    在这里插入图片描述

    4、漂亮地输出

    默认情况下,Gson以紧凑格式打印JSON,即字段名称及其值,对象字段以及JSON输出中数组内的对象等之间将没有空格。

    {"id":1,"firstName":"Lokesh","lastName":"Gupta", "emailId":"howtogoinjava@gmail.com"}
    

    但是,这种紧凑的JSON可能很难阅读。因此,GSON提供了一个漂亮的打印选项,可以在其中打印JSON,以便于更加方便阅读。

    		Gson gson = new GsonBuilder()
                    .setPrettyPrinting()
                    .create();
    		
    		Employee employeeObj = new Employee(1, "Lokesh", "Gupta", "howtogoinjava@gmail.com");
    		
    		System.out.println(gson.toJson(employeeObj));
    

    运行结果:

    在这里插入图片描述

    5、JSON array --> Java array/list

    5.1 、 JSON array -->Java对象

    users.json:

    [
        {
          "name": "Alex",
          "id": 1
        },
        {
          "name": "Brian",
          "id": 2
        },
        {
          "name": "Charles",
          "id": 3
        }
    ]
    

    User.java:

    public class User 
    {
        private long id;
        private String name;
         
        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
     
        @Override
        public String toString() {
            return "User [id=" + id + ", name=" + name + "]";
        }
    }
    

    将json数组反序列化为Java对象数组:

    String userJson = "[{'name': 'Alex','id': 1}, "
                    + "{'name': 'Brian','id':2}, "
                    + "{'name': 'Charles','id': 3}]";
             
    Gson gson = new Gson(); 
     
    User[] userArray = gson.fromJson(userJson, User[].class);  
     
    for(User user : userArray) {
        System.out.println(user);
    }
    

    运行结果:
    在这里插入图片描述


    5.2 、JSON array–>List

    将json数组反序列化为根–到Java对象列表:

    		String userJson = "[{'name': 'Alex','id': 1}, " + "{'name': 'Brian','id':2}, " + "{'name': 'Charles','id': 3}]";
    
    		Gson gson = new Gson();
    
    		java.lang.reflect.Type userListType = new TypeToken<ArrayList<User>>() {
    		}.getType();
    
    		ArrayList<User> userArray = gson.fromJson(userJson, userListType);
    
    		for (User user : userArray) {
    			System.out.println(user);
    		}
    
    

    运行结果:

    在这里插入图片描述


    5.3 、JSON array–>成员变量

    如果Json数组是非根对象,则Gson可以将JSON数组解析为成员变量。我们可以按通常的方式使用fromJson()方法,将json数组解析为所需的Java数组或列表。

    department.json:

    {
        "id"    : 1,
        "name"  : "HR",
        "users" : [
            {
              "name": "Alex",
              "id": 1
            },
            {
              "name": "Brian",
              "id": 2
            },
            {
              "name": "Charles",
              "id": 3
            }
        ]
    

    5.3.1、数组类型成员变量

    Department.java:

    public class Department {
        private long id;
        private String name;
        private User[] users;
        //省略getter/setter、构造方法、toString方法
    }
    

    JsonArrayToMemberArray.java:

    String departmentJson = "{'id' : 1, "
            + "'name': 'HR',"
            + "'users' : ["
                + "{'name': 'Alex','id': 1}, "
                + "{'name': 'Brian','id':2}, "
                + "{'name': 'Charles','id': 3}]}";
     
    Gson gson = new Gson(); 
     
    Department department = gson.fromJson(departmentJson, Department.class);  
     
    System.out.println(department);
    

    运行结果:

    在这里插入图片描述

    5.3.2、List类型成员变量

    将json数组反序列化为List类型成员变量。

    Department2.java:

    public class Department2 {
    	private long id;
    	private String name;
    	private List<User> users;	
       //省略getter/setter、构造方法、toString方法
    }	
    

    转换:

    		String departmentJson = "{'id' : 1, "
    		        + "'name': 'HR',"
    		        + "'users' : ["
    		            + "{'name': 'Alex','id': 1}, "
    		            + "{'name': 'Brian','id':2}, "
    		            + "{'name': 'Charles','id': 3}]}";
    		 
    		Gson gson = new Gson(); 
    		 
    		Department2 department = gson.fromJson(departmentJson, Department2.class);  
    		 
    		System.out.println(department);
    

    运行结果:

    在这里插入图片描述

    6、JSON <---->Set

    6.1、Set–>JSON

    使用Gson.toJson()方法将HashSet序列化为JSON:

    		Set<String> userSet = new HashSet<String>();
    		userSet.add("Alex");
    		userSet.add("Brian");
    		userSet.add("Charles");
    		 
    		Gson gson = new Gson(); 
    		 
    		String jsonString= gson.toJson(userSet);  
    		 
    		System.out.println(jsonString);
    

    运行结果:

    在这里插入图片描述


    6.2、JSON–>Set

    使用Gson.fromJson()方法和TypeToken将JSON反序列化为HashSet:

    		String jsonString = "['Alex','Brian','Charles','Alex']";
    		 
    		Gson gson = new Gson(); 
    		 
    		java.lang.reflect.Type setType = new TypeToken<HashSet<String>>(){}.getType();
    		 
    		Set<String> userSet = gson.fromJson(jsonString, setType);  
    		 
    		System.out.println(userSet);
    

    运行结果:
    在这里插入图片描述


    7、Null值处理

    Gson中实现的默认行为是忽略空对象字段。

    例如,如果在Employee对象中未指定电子邮件(即email为null),则电子邮件将不会被序列化JSON输出。Gson会忽略null字段,因为此行为允许使用更紧凑的JSON输出格式。


    7.1、如何在序列化时允许空值

    要配置Gson实例以输出null,我们必须使用GsonBuilder对象的serializeNulls()。

    Gson gson = new GsonBuilder()
            .serializeNulls()
            .create();
    

    8、版本支持

    应用程序随着时间变化,模型类也随之变化。有时候更新/删除字段可能会被打断。

    所有这些更改都可以使用@Since注释进行标记,以跟踪模型类,在这些系统使用反序列化JSON数据进行交换时,与其他系统的应用程序交互不会中断。

    8.1、@Since注解

    在Gson中,可以使用@Since注释维护同一对象的多个版本。可以在类,字段以及将来的方法中使用此注释。它采用单个参数– ignoreVersionsAfter。

    当我们为Gson实例配置版本号“ M.N”时,所有标记有版本大于M.N的类字段都将被忽略。例如,如果我们将Gson配置为版本号“ 1.2”,则所有版本号更高的字段(例如1.3、1.4…)都将被忽略。

    @Since(1.2)
    private String email;
    

    8.2、如何使用@Since注解编写版本化的类

    在Employee类下面,我们对三个字段进行了版本控制,即firstName,lastName和email。

    public class Employee 
    {
        private Integer id;
     
        @Since(1.0)
        private String firstName;
         
        @Since(1.1)
        private String lastName;
         
        @Since(1.2)
        private String email;
    }
    

    8.3、创建具备版本支持的Gson实例

    要创建使用过@Since注解的Gson实例,需要使用GsonBuilder.setVersion()方法:

    Gson gson = new GsonBuilder()
                .setVersion(1.1)
                .create();
    

    8.4、实例

    8.4.1、 具备版本支持的序列化

    让序列号以上的Employee对象序列化。

    Employee employeeObj = new Employee(1, "Lokesh", "Gupta", "howtogoinjava@gmail.com");
     
    Gson gson = new GsonBuilder()
            .setVersion(1.1)
            .setPrettyPrinting()
            .create();
     
    System.out.println(gson.toJson(employeeObj));
    

    输出:

    {
      "id": 1,
      "firstName": "Lokesh",
      "lastName": "Gupta"
    }
    

    8.4.2、具备版本支持的反序列化

    我们将JSON字符串反序列化为版本号为Employee的对象。

    String json = "{'id': 1001, "
                    + "'firstName': 'Lokesh',"
                    + "'lastName': 'Gupta',"
                    + "'email': 'howtodoinjava@gmail.com'}";
     
    Gson gson = new GsonBuilder()
            .setVersion(1.1)
            .setPrettyPrinting()
            .create();
     
    Employee employeeObj = gson.fromJson(json, Employee.class);
     
    System.out.println(employeeObj);
    

    输出:

    Employee [id=1001, firstName=Lokesh, lastName=Gupta, email=null]
    

    9、更改Java对象和JSON的字段名映射

    在此Gson @SerializedName示例中,演示在序列化和反序列化过程中更改json和java对象之间的字段名称。

    9.1、@SerializedName

    默认情况下,我们假设Java模型类和JSON将具有完全相同的字段名称。

    但有时情况并非如此,某些名称有所不同。现在我们必须将json中的someName映射到Java类中的someOtherName。这是@SerializedName注解用到的地方。

    @SerializedName注解指示带注解的成员变量应使用提供的名称值作为其字段名称序列化为JSON。此注解将覆盖可能一直在使用GsonBuilder类的任何FieldNamingPolicy,包括默认的字段命名策略。

    请注意,在此注解中指定的值必须是有效的JSON字段名称。

    注解包含属性

    • value –序列化或反序列化时所需的字段名称。
    • alternate–反序列化时字段的备用名称。除了“值”属性外,它还提供了更多可能的名称。如果有多个字段匹配一个属性,则Gson将使用最后处理的那个。

    9.2、序列化期时更改字段名称

    让我们以只有四个字段的Employee类为例。我们要创建一个JSON,其中“ email”被写为字段名“ emailId”:

    public class Employee 
    {
        private Integer id;
        private String firstName;
        private String lastName;
     
        @SerializedName(value = "emailId", alternate = "emailAddress")
        private String email;
    }
    

    让我们序列化一个Employee实例并查看JSON输出:

    Employee emp = new Employee(1001, "Lokesh", "Gupta", "howtodoinjava@gmail.com");
     
    Gson gson = new GsonBuilder().setPrettyPrinting().create();  
     
    System.out.println(gson.toJson(emp));
    

    输出:

    {
      "id": 1001,
      "firstName": "Lokesh",
      "lastName": "Gupta",
      "emailId": "howtodoinjava@gmail.com"
    }
    

    9.3、反序列化时更改字段名称

    在将JSON反序列化为Java类的过程中映射不同的字段名称:

    Json:

    {
      "id": 1001,
      "firstName": "Lokesh",
      "lastName": "Gupta",
      "email": "howtodoinjava@gmail.com",
      "emailAddress": "admin@gmail.com"
    }
    

    Main.java:

    String json = "{'id': 1001,"
            + "'firstName': 'Lokesh',"
            + "'lastName': 'Gupta',"
            + "'email': 'howtodoinjava@gmail.com',"
            + "'emailAddress': 'admin@gmail.com'}";
             
    Gson gson = new GsonBuilder().setPrettyPrinting().create(); 
     
    Employee emp = gson.fromJson(json, Employee.class);
     
    System.out.println(emp);
    

    输出:

    Employee [id=1001, firstName=Lokesh, lastName=Gupta, email=admin@gmail.com]
    

    10、排除或忽略字段

    Gson允许我们从Java类中排除或忽略不希望包含在序列化和反序列化中的字段。

    Gson支持许多内置机制,用于排除顶级类,字段和字段类型。

    10.1、@Expose注解

    GSON @Expose注解(com.google.gson.annotations.Expose)可用于标记对象序列化或反序列化时是否公开(包括活不包括)的字段。

    @Expose注释在要显式指定应进行序列化或反序列化的所有字段的编程方式中很有用。

    10.1.1. 怎么用 @Expose

    @Expose是可选的,并提供两个配置参数:

    • serialize –如果为true,则在序列化时会在JSON中写出带有此注解的字段。
    • deserialize –如果为true,则从JSON反序列化带有此注解的字段。
    @Expose(serialize = false) 
    private String lastName;
     
    @Expose (serialize = false, deserialize = false) 
    private String emailAddress;
    

    10.1.2、创建Gson实例

    如果我们使用 new Gson() 创建Gson并执行toJson() 和 fromJson() 方法,则@Expose将不会对序列化和反序列化产生任何影响。要使用此批注,我们必须使用GsonBuilder类及其excludeFieldsWithoutExposeAnnotation()方法创建Gson实例。

    Gson gson = new GsonBuilder()
            .excludeFieldsWithoutExposeAnnotation()
            .create();
    

    10.2、用修饰符排除字段

    10.2.1、transient 字段

    默认情况下,如果我们仅将字段标记为瞬时态,则Gson会将字段从序列化和反序列化中排除。

    请记住,它无法阻止单向转换。它同时阻止了两者。

    transient 具有与@Expose相同的效果(serialize = false,deserialize = false)。

    @Expose(serialize = false) 
    private String lastName;
     
    private transient String emailAddress;
    

    10.2.2、其他修饰符

    通过使用GsonBuilder的excludeFieldsWithModifiers()方法,我们可以排除具有某些公共修饰符的字段。

    例如,我们要排除一个类的所有静态成员,我们可以这样创建Gson对象:

    Gson gson = new GsonBuilder()
            .excludeFieldsWithModifiers(Modifier.STATIC)
            .create();
    

    我们可以使用任意数量的Modifier常量来“ excludeFieldsWithModifiers”方法。例如:

    Gson gson = new GsonBuilder()
            .excludeFieldsWithModifiers(Modifier.STATIC, 
                                Modifier.TRANSIENT, 
                                Modifier.VOLATILE)
            .create();
    

    10.3、排除策略

    如果以上任何一种技术都不适合我们,那么我们可以创建自己的策略。

    ExclusionStrategy用于确定是否应将字段或顶级类作为JSON输出/输入的一部分进行序列化或反序列化。

    • 对于序列化,如果shouldSkipClass(Class)或shouldSkipField(fieldAttributes)方法返回true,则该类或字段类型将不属于JSON输出。
    • 对于反序列化,如果shouldSkipClass(Class)或shouldSkipField(fieldAttributes)方法返回true,则不会将其设置为Java对象结构的一部分。

    例如,在ExclusionStrategy定义下面,将排除所有使用@Hidden注释注释的字段:

    //public @interface Hidden {
        // some implementation here
    //}
     
    // Excludes any field (or class) that is tagged with an "@Hidden"
    public class HiddenAnnotationExclusionStrategy implements ExclusionStrategy 
    {
        public boolean shouldSkipClass(Class<?> clazz) {
            return clazz.getAnnotation(Hidden.class) != null;
        }
     
        public boolean shouldSkipField(FieldAttributes f) {
            return f.getAnnotation(Hidden.class) != null;
        }
    }
    

    要使用此排除策略,在GsonBuilder对象中进行设置:

    GsonBuilder builder = new GsonBuilder();
    builder.setExclusionStrategies( new HiddenAnnotationExclusionStrategy() );
     
    Gson gson = builder.create();
    

    四、GsonBuilder

    对于简单的用例,使用’Gson gson = new Gson();’ 标准配置就足够了。 但是,如果打算自定义Gson的行为,则可以使用GsonBuilder自定义的配置来创建新的Gson实例。

    GsonBuilder类提供一个.create()方法,该方法返回一个Gson实例。

    Gson gson = new GsonBuilder().create(); 
    

    1、GsonBuilder.setPrettyPrinting()–漂亮地打印JSON

    默认情况下,Gson将创建紧凑的JSON字符串。这对于减少通过网络传输的数据量非常有用。

    但是,这种紧凑的JSON对开发人员进行开发/调试应用程序时不友好。使用漂亮的打印来格式化JSON输出:

    Gson gson = new GsonBuilder()
            .setPrettyPrinting()
            .create(); 
    

    2、FieldNamingPolicy

    FieldNamingPolicy枚举在序列化期间为JSON字段名称提供了几种标准命名约定。

    它有助于Gson实例将Java字段名称正确转换为所需的JSON字段名称。

    注意:以下任何命名约定均不会影响以@SerializedName注释的字段。我们将验证使用User类的每个策略生成的名称。

    User.java:

    public class User 
    {
        private int id;
        private String first_Name;
        private String lastName;
        private String _email;
    }
    

    如何使用FieldNamingPolicy:

    User user = new User(1, "Lokesh", "Gupta", "admin@howtodoinjava.com");
             
    Gson gson = new GsonBuilder()
                    .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
                    .setPrettyPrinting().create(); 
     
    System.out.println(gson.toJson(user));
    

    以下演示每种命名策略下转换的不同的名称。


    2.1、FieldNamingPolicy.IDENTITY

    使用此命名策略字段名称不变。这个是默认的策略:

    {
      "id": 1,
      "first_Name": "Lokesh",
      "lastName": "Gupta",
      "_email": "admin@howtodoinjava.com"
    }
    

    2.2、FieldNamingPolicy.LOWER_CASE_WITH_DASHES

    Gson会将Java字段名称从其驼峰大小写形式修改为小写的字段名称,其中每个单词都用破折号(-)分隔。

    {
      "id": 1,
      "first_-name": "Lokesh",
      "last-name": "Gupta",
      "_email": "admin@howtodoinjava.com"
    }
    

    2.3、FieldNamingPolicy.LOWER_CASE_WITH_DOTS

    Gson会将Java字段名称从其驼峰大小写形式修改为小写的字段名称,其中每个单词都用点(.)分隔:

    {
      "id": 1,
      "first_.name": "Lokesh",
      "last.name": "Gupta",
      "_email": "admin@howtodoinjava.com"
    }
    

    2.4、FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES

    Gson会将Java字段名称从其驼峰大小写形式修改为小写的字段名称,其中每个单词都用下划线(_)分隔。

    {
      "id": 1,
      "first__name": "Lokesh",
      "last_name": "Gupta",
      "_email": "admin@howtodoinjava.com"
    }
    

    2.5、 FieldNamingPolicy.UPPER_CAMEL_CASE

    Gson将确保序列化为JSON格式的Java字段名称的第一个“字母”大写:

    {
      "Id": 1,
      "First_Name": "Lokesh",
      "LastName": "Gupta",
      "_Email": "admin@howtodoinjava.com"
    }
    

    2.6、FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES

    Gson将确保在将Java字段名称的第一个“字母”序列化为JSON格式时将其大写,并且单词之间将使用空格分隔:

    {
      "Id": 1,
      "First_ Name": "Lokesh",
      "Last Name": "Gupta",
      "_Email": "admin@howtodoinjava.com"
    }
    

    3、GsonBuilder.serializeNulls()——空值的序列化

    默认情况下,Gson会在序列化过程中忽略null值。但是,有时我们想序列化具有空值的字段,以便它必须出现在JSON中。为此,可以使用serializeNulls()方法:

    Employee employeeObj = new Employee(1, "Lokesh", "Gupta", null);
                     
    Gson gson = new GsonBuilder()
            .serializeNulls()
            .setPrettyPrinting().create(); 
     
    System.out.println(gson.toJson(employeeObj));
    

    输出:

    {
      "id": 1,
      "firstName": "Lokesh",
      "lastName": "Gupta",
      "emailId": null
    }
    

    4、GsonBuilder.setExclusionStrategies()

    ExclusionStrategy用于确定是否应将字段或顶级类作为JSON输出/输入的一部分进行序列化或反序列化。

    • 对于序列化,如果shouldSkipClass(Class)方法返回true,则该类或字段类型将不会在JSON中输出。
    • 对于反序列化,如果shouldSkipClass(Class)返回true,则不会将其设置为Java对象结构的一部分。

    shouldSkipField(attribute)方法也是相同的规则。

    在下面的示例中,使用@NPI注解和属于Account类的实例的成员字段不会进行序列化和反序列化。

    Gson gson = new GsonBuilder()
        .setExclusionStrategies(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return f.getAnnotation(NPI.class) != null;
            }
     
            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return clazz.getAnnotation(Account.class) != null;
            }
        })
        .setPrettyPrinting()
        .create(); 
    

    5、GsonBuilder.setLenient()——宽松的JSON语法规则

    在反序列化期间,Gson使用了一个宽松的JsonReader类。这意味着它仅接受兼容的JSON输入。

    如果JSON违反结构规则之一,它将抛出MalformedJsonException。如果我们将lenient设置为true,则它将忽视某些违规行为,并尝试读取格式不正确的JSON。

    Gson gson = new GsonBuilder()
            .setLenient()
            .setPrettyPrinting().create(); 
    

    五、JsonReader

    使用Gson JsonReader类,该类是基于拉式的流JSON解析器。它有助于将JSON作为令牌流读取。

    1、JsonReader

    • JsonReader是流式JSON解析器,也是pull parser的示例。pull parser解析JSON令牌并将其推送到事件处理程序中。
    • 它有助于读取JSON(RFC 7159)编码值作为令牌流。
    • 它读取字面值(字符串,数字,布尔值和null)以及对象和数组的开始和结束定界符。
    • 令牌以深度优先顺序遍历,与JSON文档中出现的顺序相同。

    2、Tokens

    在流模式下,每个JSON数据都被视为一个单独的令牌。

    当我们使用JsonReader对其进行处理时,每个令牌将被顺序处理。例如,

    {
        "name":"Lokesh"
    }
    

    在使用JsonReader进行解析时,以上JSON将生成4个令牌:

    • Token 1 = {
    • Token 2 = name
      • Token 3 = Lokesh
    • Token 4 = }

    3、如何创建GSON JsonReader

    我们可以使用它的简单构造函数创建一个JsonReader实例,该实例接受java.io.Reader类型的输入流。

    String json = "{}";
    JsonReader jsonReader = new JsonReader( new StringReader(json) );
    

    我们可以根据JSON流的来源使用以下阅读器之一:

    • BufferedReader
    • LineNumberReader
    • CharArrayReader
    • InputStreamReader
    • FileReader
    • FilterReader
    • PushbackReader
    • PipedReader
    • StringReader

    4、读取JSON流

    创建包含有效JSON源的JsonReader之后,我们可以开始遍历流令牌并查看令牌值。

    以下是使用JsonReader以令牌形式读取简单JSON的示例:

    import java.io.IOException;
    import java.io.StringReader;
     
    import com.google.gson.stream.JsonReader;
    import com.google.gson.stream.JsonToken;
     
    public class Main 
    {
        public static void main(String[] args) throws Exception 
        {
     
            String json = "{'id': 1001,'firstName': 'Lokesh','lastName': 'Gupta','email': null}";
     
            JsonReader jsonReader = new JsonReader(new StringReader(json));
            jsonReader.setLenient(true);
             
            try
            {
                while (jsonReader.hasNext()) 
                {
                    JsonToken nextToken = jsonReader.peek();
                     
                    if (JsonToken.BEGIN_OBJECT.equals(nextToken)) {
     
                        jsonReader.beginObject();
     
                    } else if (JsonToken.NAME.equals(nextToken)) {
     
                        String name = jsonReader.nextName();
                        System.out.println("Token KEY >>>> " + name);
     
                    } else if (JsonToken.STRING.equals(nextToken)) {
     
                        String value = jsonReader.nextString();
                        System.out.println("Token Value >>>> " + value);
     
                    } else if (JsonToken.NUMBER.equals(nextToken)) {
     
                        long value = jsonReader.nextLong();
                        System.out.println("Token Value >>>> " + value);
     
                    } else if (JsonToken.NULL.equals(nextToken)) {
     
                        jsonReader.nextNull();
                        System.out.println("Token Value >>>> null");
                         
                    } else if (JsonToken.END_OBJECT.equals(nextToken)) {
     
                        jsonReader.endObject();
     
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                jsonReader.close();
            }
        }
    }
    

    输出:

    Token KEY >>>> id
    Token Value >>>> 1001
     
    Token KEY >>>> firstName
    Token Value >>>> Lokesh
     
    Token KEY >>>> lastName
    Token Value >>>> Gupta
     
    Token KEY >>>> email
    Token Value >>>> null
    

    在上面的示例中:

    • 如果JsonReader的hasNext()方法具有更多令牌,则返回true。
    • peek()方法返回下一个JSON令牌,但不移至该令牌。
    • 随后多次调用peek()将返回相同的JSON令牌。
    • 可以使用JsonToken类的常量检查返回令牌的类型。
    • 使用beginArray()和endArray()方法检查数组的左括号和右括号“ [”和“]”。使用beginObject()和endObject()方法检查对象的左括号和右括号“ {”和“}”。
    • 令牌的密钥为JsonToken.NAME类型。使用nextName()方法获取密钥名称。
    • 确定令牌的类型后,使用诸如nextLong(),nextString(),nextInt()等方法获取令牌的值。可以使用nextNull()或skipValue()使用空文字。
    • 所有next …()方法都返回当前标记的值,并将内部指针移至下一个。
    • 当遇到未知名称时,严格的解析器应该失败,并带有异常。宽大的解析器应调用skipValue()以递归地跳过该值的嵌套令牌,否则可能会发生冲突。

    六、JsonParser

    Gson JsonParser用于将Json数据解析为JsonElement的解析树,从而解析为JsonObject。

    JsonObject可用于使用JSON字符串中的相应键来访问值。

    1、创建JsonParser

    JsonParser类只有一个默认构造函数,并且不需要任何参数或配置。

    JsonParser parser = new JsonParser();
    

    2、转化JSON

    JsonParser类提供3种方法来提供JSON作为源并将其解析为JsonElements树。

    • JsonElement parse(JsonReader json)–使用JsonReader读取JSON作为令牌流,并从JSON流中返回下一个值作为分析树。
    • JsonElement parse(java.io.Reader json)–使用指定的阅读器读取JSON并将JSON字符串解析为解析树。
    • JsonElement parse(java.lang.String json)–将指定的JSON字符串解析为解析树。

    如果指定的文本不是有效的JSON,则这三个方法都将抛出JsonParseException和JsonSyntaxException。


    3、 JsonElement, JsonObject 和JsonArray

    在JsonElement树中解析了JSON字符串后,我们就可以使用它的各种方法来访问JSON数据元素。

    例如,使用一种类型检查方法找出它代表什么类型的JSON元素:

    jsonElement.isJsonObject();
    jsonElement.isJsonArray();
    jsonElement.isJsonNull();
    jsonElement.isJsonPrimitive();
    

    我们可以使用相应的方法将JsonElement转换为JsonObject和JsonArray:

    JsonObject jsonObject = jsonElement.getAsJsonObject();
    JsonArray jsonArray = jsonElement.getAsJsonArray();
    

    一旦有了JsonObject或JsonArray实例,就可以使用其get()方法从中提取字段。


    4、Gson JsonParser 示例

    使用JsonParser将JSON解析为JsonElement(和JsonObject),并使用键获取JSON值:

    import com.google.gson.JsonElement;
    import com.google.gson.JsonObject;
    import com.google.gson.JsonParser;
     
    public class Main 
    {
        public static void main(String[] args) throws Exception 
        {
            String json = "{'id': 1001, "
                    + "'firstName': 'Lokesh',"
                    + "'lastName': 'Gupta',"
                    + "'email': 'howtodoinjava@gmail.com'}";
     
            JsonElement jsonElement = new JsonParser().parse(json);
             
            JsonObject jsonObject = jsonElement.getAsJsonObject();
     
            System.out.println( jsonObject.get("id") );
            System.out.println( jsonObject.get("firstName") );
            System.out.println( jsonObject.get("lastName") );
            System.out.println( jsonObject.get("email") );
        }
    }
    

    输出:

    1001
    "Lokesh"
    "Gupta"
    "howtodoinjava@gmail.com"
    

    5、使用fromJson() 获取JsonObject

    我们可以使用Gson实例及其fromJson()方法来获得相同的结果:

    String json = "{'id': 1001, "
            + "'firstName': 'Lokesh',"
            + "'lastName': 'Gupta',"
            + "'email': 'howtodoinjava@gmail.com'}";
     
    JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
     
    System.out.println(jsonObject.get("id"));
    System.out.println(jsonObject.get("firstName"));
    System.out.println(jsonObject.get("lastName"));
    System.out.println(jsonObject.get("email"));
    

    输出:

    String json = "{'id': 1001, "
            + "'firstName': 'Lokesh',"
            + "'lastName': 'Gupta',"
            + "'email': 'howtodoinjava@gmail.com'}";
     
    JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
     
    System.out.println(jsonObject.get("id"));
    System.out.println(jsonObject.get("firstName"));
    System.out.println(jsonObject.get("lastName"));
    System.out.println(jsonObject.get("email"));
    

    6、迭代JSON树结构

    这是一个完整的示例,展示了如何迭代从JsonReader获得的JsonElement:

    JsonParser parser = new JsonParser();
    
    String json = "{ \"f1\":\"Hello\",\"f2\":{\"f3:\":\"World\"}}";
    
    JsonElement jsonTree = parser.parse(json);
    
    if(jsonTree.isJsonObject()){
        JsonObject jsonObject = jsonTree.getAsJsonObject();
    
        JsonElement f1 = jsonObject.get("f1");
    
        JsonElement f2 = jsonObject.get("f2");
    
        if(f2.isJsonObject()){
            JsonObject f2Obj = f2.getAsJsonObject();
    
            JsonElement f3 = f2Obj.get("f3");
        }
    
    }
    

    七、自定义序列化和反序列化

    Gson在默认序列化和反序列化方面提供了非常出色的功能。

    不过,我们可能会遇到默认和内置自定义选项无法解决我们问题的情况。在这种情况下,我们可以通过两个接口JsonSerializer和JsonDeserializer使用自定义序列化和反序列化。

    1、自定义序列化

    1.1、JsonSerializer接口

    JsonSerializer.java:

    public interface JsonSerializer<T> 
    {
        public JsonElement serialize(T value, Type type,
                JsonSerializationContext jsonSerializationContext) {
        }
    }
    

    为Json创建自定义序列化程序后,我们还需要通过GsonBuilder.registerTypeAdapter(Type,Object)注册该序列化程序。

    当Gson遇到指定类型的字段时,它会在序列化期间调用其回调方法serialize()。


    1.2、自定义序列化示例

    假设我们遇到一种情况,我们必须将Java对象序列化为json,这样所有布尔值都应写为1或0,而不是打印true或false。

    让我们为该要求编写自定义序列化程序。

    BooleanSerializer.java:

    import com.google.gson.JsonElement;
    import com.google.gson.JsonPrimitive;
    import com.google.gson.JsonSerializationContext;
    import com.google.gson.JsonSerializer;
     
    public class BooleanSerializer implements JsonSerializer<Boolean> {
     
        public JsonElement serialize(Boolean aBoolean, Type type,
            JsonSerializationContext jsonSerializationContext) 
        {
            if(aBoolean){
               return new JsonPrimitive(1);
            }
            return new JsonPrimitive(0);
        }
    }
    

    让我们编写一个程序,使用registerTypeAdapter()注册JsonSerializer实例,并使用该程序将Java对象序列化为json。

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
     
    public class Main 
    {
        public static void main(String[] args) throws Exception 
        {
            Employee emp = new Employee(1, "Lokesh", "Gupta", "howtodoinjava@gmail.com", true);
             
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(Boolean.class, new BooleanSerializer())
                    .setPrettyPrinting()
                    .create();
             
            String json = gson.toJson(emp);
             
            System.out.println(json);
        }
    }
    

    注意程序输出,键“ active”的值被序列化为1:

    {
      "id": 1,
      "firstName": "Lokesh",
      "lastName": "Gupta",
      "email": "howtodoinjava@gmail.com",
      "active": 1
    }
    

    2、自定义反序列化

    2.1、JsonDeserializer接口

    定制反序列化器必须实现JsonDeserializer接口。JsonDeserializer接口如下所示:

    JsonDeserializer.java:

    public interface JsonDeserializer<T> 
    {    
        public Boolean deserialize(JsonElement jsonElement, 
            Type type, JsonDeserializationContext jsonDeserializationContext) 
            throws JsonParseException;
    }
    

    为Json创建自定义反序列化器之后,我们还需要通过GsonBuilder.registerTypeAdapter(Type,Object)注册此反序列化器。

    当Gson遇到指定类型的字段时,它会在序列化期间调用其回调方法deserialize()。

    2.2、自定义反序列化示例

    假设某些服务将日期字段分别分为天,月和年等部分分别返回给我们。在JSON字符串中,它们可能有意义,但是在Java中,它们只有作为单个java.time.LocalDate对象的一部分时才有意义。

    employee.json:

    {
      "id": 1,
      "firstName": "Lokesh",
      "lastName": "Gupta",
      "email": "howtodoinjava@gmail.com",
      "day": 11,
      "month": 8,
      "year": 2019
    }
    

    我们要自定义反序列化并将最后三个字段组合为LocalDate对象。

    我们的Employee看起来像这样。包括必要的getter和setter以及构造函数。

    Employee.java:

    public class Employee 
    {
        private Integer id;
        private String firstName;
        private String lastName;
        private String email;
        private LocalDate dob;
    }
    

    自定义反序列化器类如下所示:

    EmployeeDeserializer.java:

    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonObject;
    import com.google.gson.JsonParseException;
     
    public class EmployeeDeserializer implements JsonDeserializer<Employee> 
    {  
        @Override
        public Employee deserialize(JsonElement json, Type typeOfT, 
                    JsonDeserializationContext context) throws JsonParseException 
        {
            JsonObject jsonObject = json.getAsJsonObject();
     
            LocalDate localDate = LocalDate.of(
                    jsonObject.get("year").getAsInt(),
                    jsonObject.get("month").getAsInt(),
                    jsonObject.get("day").getAsInt()
            );
     
            return new Employee(
                    jsonObject.get("id").getAsInt(), 
                    jsonObject.get("firstName").getAsString(), 
                    jsonObject.get("lastName").getAsString(), 
                    jsonObject.get("email").getAsString(), 
                    localDate);
        }
    }
    

    注册反序列化器,然后将给定的JSON解析为java对象:

    Main.java:

    public class Main 
    {
        public static void main(String[] args) throws Exception 
        {
            String json = "{'id': 1001,"
                        + "'firstName': 'Lokesh',"
                        + "'lastName': 'Gupta',"
                        + "'email': 'howtodoinjava@gmail.com', "
                        + "'day': 11, "
                        + "'month': 8, "
                        + "'year': 2019}";
             
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(Employee.class, new EmployeeDeserializer())
                    .create();
             
            Employee employee = gson.fromJson(json, Employee.class);
             
            System.out.println(employee);
        }
    }
    

    注意程序输出将3个单独的字段组合到单个LocalDate对象中:

    Employee [id=1001, 
            firstName=Lokesh, 
            lastName=Gupta, 
            email=howtodoinjava@gmail.com, 
            dob=2019-08-11]
    



    参考:
    【1】:Gson
    【2】:Gson – Introduction
    【3】:Gson – Installation
    【4】:GSON - Gson
    【5】:GSON – Serialize and Deserialize JSON
    【6】:Gson – Pretty Printing for JSON Output
    【7】:GSON – Parse JSON array to Java array or list
    【8】:GSON – Serialize and deserialize JSON to Set
    【9】:Gson – GsonBuilder Configuration Examples
    【10】:Gson @Since – Version Support
    【11】:Gson @SerializedName
    【12】:Gson – JsonReader
    【13】:Gson – JsonReader
    【14】:Gson – JsonParser
    【15】:GSON - JsonParser

    展开全文
  • 非常详细的json使用方法。包括对象和json之间的相互转换,集合和json之间的相互转换,自己按照节点解析。gson功能真的很强大。
  • Gson基本用法

    万次阅读 多人点赞 2018-05-12 14:25:03
    Gson是谷歌官方推出的支持 JSON -- Java Object 相互转换的 Java序列化/反序列化 库,之前由于没有用过,所以学习一下。 1. 导入Android Studio工程 dependencies { implementation '...

    Gson是谷歌官方推出的支持 JSON -- Java Object 相互转换的 Java序列化/反序列化 库,之前由于没有用过,所以学习一下。

    1. 导入Android Studio工程

    dependencies {
        implementation 'com.google.code.gson:gson:2.8.4'
    }
    

    2. 简单的 Java Object 序列化/反序列化

    序列化

    假如有一个User类,拥有 name, email, age, isDeveloper 四个属性,如下:

    User userObject = new User(  
        "Norman", 
        "norman@futurestud.io", 
        26, 
        true
    );
    

    使用Gson将它序列化:

    Gson gson = new Gson();
    String userJson = gson.toJson(userObject);
    

    得到的结果如下:

    {
    	"isDeveloper":true,
    	"name":"Norman",
    	"age":26,
    	"email":"norman@futurestud.io"
    }
    

    反序列化

    先定义一段JSON字符串

    String userJson = "{'isDeveloper':false,'name':'xiaoqiang','age':26,'email':'578570174@qq.com'}";
    

    Gson反序列化

    User user = gson.fromJson(userJson, User.class);
    

    debug一下,查看结果
    这里写图片描述
    反序列化成功!

    3. 嵌套 Java Object 的序列化/反序列化

    也就是说,一个类里面还包含有其它类。比如User类里面还有个用户地址UserAddress类,JSON结构如下:

    {
        "age": 26,
        "email": "578570174@qq.com",
        "isDeveloper": true,
        "name": "chenrenxiang",
    
        "userAddress": {
            "city": "Magdeburg",
            "country": "Germany",
            "houseNumber": "42A",
            "street": "Main Street"
        }
    }
    

    那么这种Java Object该如何序列化/反序列化呢?和上面一样。也就是说和 2 里面介绍的方法一样


    4. Array 和 List 的序列化/反序列化

    序列化
    序列化和前面介绍的方法是一样的

    反序列化
    那就有些不同了,不然也不用分开写。

    1 Array的反序列化
    先假设有一个name数组,定义JSON格式如下:

    String namesJson = "['xiaoqiang','chenrenxiang','hahaha']";
    

    然后使用Gson去反序列化它:

    Gson gson = new Gson();
    String[] nameArray = gson.fromJson(namesJson, String[].class);
    

    得到的nameArray如下:
    这里写图片描述
    其实这和 2 里面介绍的反序列化方法仍然是一样的。可以看到,Gson的反序列化都是调用 Gson.fromJson(...)方法,传入JSON字符串,以及这段JSON字符串对应的Object类型。

    2 List的反序列化

    String userJson = "[{'isDeveloper':false,'name':'xiaoqiang','age':26,'email':'578570174@qq.com'},{'isDeveloper':true,'name':'xiaoqiang123','age':27,'email':'578570174@gmail.com'}]";
    
    Gson gson = new Gson();
    Type userListType = new TypeToken<ArrayList<User>>(){}.getType();
    
    List<User> userList = gson.fromJson(userJson, userListType); 
    

    对于List,反序列化时必须提供它的Type,通过Gson提供的TypeToken<T>.getType()方法可以定义当前List的Type。反序列化后结果如下:

    这里写图片描述

    那么,如果一个Java Object里包含List类型的变量,该如何反序列化这个Object呢?答案是,和 2 一样就行了,无需为其内部的List提供Type

    5. Map 和 Set 的序列化/反序列化

    Map我平时用的较多,Set用的就很少了,它们的序列化/反序列化方法和List都是一样的,反序列化的时候需要提供Type

    6. 变量值为null时的序列化/反序列化

    仍然以User类为例,如果一个User对象,里面的某个值为null,那么其序列化出来后的结果会是什么样的呢?

    先看序列化,我们先初始化一个User对象,并把其中的email变量赋值为null,再用Gson来序列化它,如下:

        User user = new User(true, "chenrenxiang", 27, null);
        Gson gson = new Gson();
        String userJson = gson.toJson(user);
    

    debug一下,得到结果如下:
    这里写图片描述

    可见,当某个变量值为null时,Gson在序列化的时候直接把这个变量忽略了。

    再来看下反序列化, 先定义一段JSON字符串,只给它一个变量值name,用User类来反序列化它,看得到的结果会是什么。

       String userJson = "{'name':'xiaoqiang'}";
       Gson gson = new Gson();
       User user = gson.fromJson(userJson, User.class);
    

    这里写图片描述
    对于JSON字符串里没有的变量,Gson在反序列化时会给它一个默认值,int类型默认为0,bool类型默认为false,String类型默认为null。

    有人不禁要问了,如果JSON字符串里某个变量的值为null,反序列化后的结果会是什么呢?我测试过了,和没有的结果是一样的。

    7. 控制序列化/反序列化 的变量名称

    仍然以User对象为例,目前User对象里有四个变量nameageemailisDeveloper。假如,某一天,JSON字符串的变量名name变成了fullName,无需紧张,我们不用把User类里的变量name改为fullName,然后把它的getset方法都改了,然后把用到get/set方法的地方全改过来。只需要用Gson提供的注解方法@SerializedName就行了,如下:

    public class User {
        private boolean isDeveloper;
        @SerializedName("fullName")
        private String name;
        private int age;
        private String email;
        ...
    }
    

    这样虽然JSON字符串里的变量名为fullName,但是反序列化后fullName的值会映射给name。同样,把一个User对象序列化,变量name会自动转换为fullName

    然而现实远比想象中复杂,这个JSON有时候传的是fullName,有时候传的是name,这时该怎么办呢? 不用担心,@SerializedName 接受两个参数,valuealternate ,顾名思义,alternate 是备选变量名,比如下面这段代码:

    public class User {
        private boolean isDeveloper;
        @SerializedName(value = "name", alternate = "fullName")
        private String name;
        private int age;
        private String email;
        ...
    }
    

    如果JSON传的是name,那么就用name的值,如果传的是fullName,那么就用fullName的值。需要注意的是,alternate只是反序列化JSON的一个备选变量名,它不会影响序列化,User对象序列化后,会使用value定义的名称为变量名。

    又想到有一个问题,在定义了value和alternate的情况下,假如JSON同时传来了name和fullName,User的name变量会接受哪个值呢? 经过测试,它会都接受。这样也是很合理的,因为Gson会对JSON中的变量一个一个地去解析,既然它可以接受name,也可以接受fullName,那么当同时传来这两个变量时,它就会分别把它们解析出来,并把值赋给User对象中的name变量。那么,name变量的值就会是后解析的那个JSON变量的值,因为它会把前一个值覆盖掉。

    8. 序列化/反序列化过程中忽略某些变量

    也许会出现这样的需求,在将某个对象序列化时,对象中的某些变量是不需要的。有可能在反序列化某个JSON字符串时,某些变量的值也是不需要的。这时就可以使用Gson提供的@Expose注解方法。使用方法如下:

    public class User {  
        @Expose()
        String name; // 参与序列化/反序列化
    
        @Expose(serialize = false, deserialize = false)
        String email; // 不参与序列化,也不参与反序列化
    
        @Expose(serialize = false)
        int age; // 只参与反序列化
    
        @Expose(deserialize = false)
        boolean isDeveloper; // 只参与序列化
    }
    

    使用这个方法,可以非常灵活地控制对象的某个/某些变量参不参与序列化/反序列化

    然而! 要使用这个注解来控制序列化/反序列化,就不能使用默认的Gson对象,新建Gson对象的方法如下:

    GsonBuilder builder = new GsonBuilder();  
    builder.excludeFieldsWithoutExposeAnnotation();  
    Gson gson = builder.create(); 
    

    注意:使用以上方式构建的Gson,在序列化/反序列化对象时,会排除所有没有添加@Expose注解的字段。

    另一个选择transient关键字 ,使用这个关键字,可以直接让变量不参与序列化/反序列化,如下:

    public class User {  
        String name;
        String email;
        int age;
        boolean transient isDeveloper; //不参与序列化/反序列化
    }
    

    当然,使用默认的Gson对象就可以。


    以上是这两天学到的Gson的基本用法,如果想进一步了解,可以参考Future Studio的 Gson教程

    展开全文
  • JSONObject和Gson用法详解

    万次阅读 2017-09-27 09:00:24
    JSONObject和Gson用法详解##1.JSONObject使用方法详解所需jar包json-lib-2.4-jdk15.jar commons-beanutils-1.8.3.jar commons-collections-3.2.1.jar commons-lang-2.5.jar commons-logging-1.1.1.jar ezmorph-...

    JSONObject和Gson用法详解

    #

    #

    1.JSONObject使用方法详解

    所需jar包

    json-lib-2.4-jdk15.jar 
    commons-beanutils-1.8.3.jar
    commons-collections-3.2.1.jar
    commons-lang-2.5.jar
    commons-logging-1.1.1.jar
    ezmorph-1.0.6.jar
    

    一般情况下除JSONObject的jar之外还需要依赖的其他5个jar包,如上所示

    其中 JSONObject 目前最新的版本为2.4,其他版本下载地址为:http://sourceforge.net/projects/json-lib/files/json-lib/

    常用的情景和实现方式

    a.前台封装Json格式的数据后转成字符串(不包含复杂对象),后台用字符串接收,转成对应的类

    • 前台实现

      var params = {
          'page': 1,
          'rows': 10,
          'pickUpTmStr': '2017-09-15 15:00',
          'sendBackTmStr': '2017-09-16 15:00',
          'day': '1',
          'id': '123',
          'sortType': 1
      };
      $.ajax({
          type: "POST",
          url: "${ctx}/w/com/selectRentalCarForPage.json.json",
          data: {'paramsStr' : JSON.stringify(params)},
          dataType:'json',
          success: function(msg){
              if(msg.resultCode=="SUCCESS"){
                  alert(msg.resultMessage);
              }else{
                  closeAllDialog();
                  alert(msg.resultMessage);
              }
          }
      });
      
    • 后台实现

      @RequestMapping(value = "/selectRentalCarForPage.json", method = RequestMethod.POST)
      public @ResponseBody IPageModule selectRentalCarForPage(HttpServletRequest request,HttpServletResponse response, 
          ModelMap model,String paramsStr) {
          IPageModule iPageModule =null;
          JSONObject jObjf = JSONObject.fromObject(paramsStr);
          Map<String,Object> paramsMap = (Map<String,Object>)JSONObject.toBean(jObjf, Map.class);
          try {   
              iPageModule = rentalCarService.selectRentalCarForPage(paramsMap);
          } catch (Exception e) {
              e.printStackTrace();
          }
          return iPageModule;
      }
      

      此为将前台接收的参数转为Map,如需要转成实体类,则可以如下实现:

      JSONObject jObjf = JSONObject.fromObject(studentStr);
      Student student = (RentalCarIntent)JSONObject.toBean(jObjf, Student.class);
      

      注:若是将参数转为对应的实体类对象,前台封装参数时的key必须要与实体类中字段对应,否则会报错

    b.前台封装Json格式的数据后转成字符串(不包含复杂对象),后台用字符串接收,转成对应的类

    • 前台实现

      var params = {
          'page': 1,
          'rows': 10,
          'pickUpTmStr': '2017-09-15 15:00',
          'sendBackTmStr': '2017-09-16 15:00',
          'day': '1',
          'id': '123',
          'sortType': 1
          'student':{
              'name':'小明',
              'sexCd':10
          }
      };
      $.ajax({
          type: "POST",
          url: "${ctx}/w/com/selectRentalCarForPage.json.json",
          data: {'paramsStr' : JSON.stringify(params)},
          dataType:'json',
          success: function(msg){
              if(msg.resultCode=="SUCCESS"){
                  alert(msg.resultMessage);
              }else{
                  closeAllDialog();
                  alert(msg.resultMessage);
              }
          }
      });
      
    • 后台实现

      @RequestMapping(value = "/selectRentalCarForPage.json", method = RequestMethod.POST)
      public @ResponseBody IPageModule selectRentalCarForPage(HttpServletRequest request,HttpServletResponse response, 
          ModelMap model,String paramsStr) {
          IPageModule iPageModule =null;
          JSONObject jObjf = JSONObject.fromObject(paramsStr);
          classMap.put("student", Student.class);
          Map<String,Object> paramsMap = (Map<String,Object>)JSONObject.toBean(jObjf, Map.class,classMap);
          try {   
              iPageModule = rentalCarService.selectRentalCarForPage(paramsMap);
          } catch (Exception e) {
              e.printStackTrace();
          }
          return iPageModule;
      }
      

      此为将前台接收的参数转为Map,如需要转成实体类,则可以如下实现:

      JSONObject jObjf = JSONObject.fromObject(studentStr);
      Student student = (Student)JSONObject.toBean(jObjf, Student.class);
      

      注:若是将参数转为对应的实体类对象,前台封装参数时的key必须要与实体类中字段对应,否则会报错,包括类中复杂对象名称,都要一一对应

      另注:classMap用法介绍

      /**字符串转java bean时,字符串中如果出现类似List , Map ,ArrayList、自定义的类型等复杂类型,解决方法如下:
      *1.Map<String, Class> classMap = new HashMap<String, Class>();
      *2.classMap.put("对象的那个特殊的属性名(集合)", 集合中的对象名.class);
      *3.最后加上一个参数(JudgementRestaurant)JSONObject.toBean(jObjf, JudgementRestaurant.class,classMap);
      */
      

    2. Gson使用方法详解

    所需jar包

    gson-2.3.1.jar
    

    常用的情景和实现方式

    a.前台封装Json格式的数据后转成字符串(不包含复杂对象),后台用字符串接收,转成对应的类

    • 前台实现

      同上(与JSONObject封装方法一致)
      
    • 后台实现

      //代码基本一致,只是转换稍有不同
      JsonObject obj = (JsonObject)new Gson().fromJson(zhouStr, JsonObject.class);
      JudgementFleet judgementFleet = new Gson().fromJson(obj.get("fleet"), JudgementFleet.class);
      //或者
      JudgementFleet judgementFleet = (JudgementFleet)new Gson().fromJson(zhouStr, JudgementFleet.class);
      
      //list
      JSONObject jsonObject = JSONObject.fromObject(zhouStr);
      List<ProductDuty> productDutyList= (List<ProductDuty>)JSONArray.toCollection(jsonObject.getJSONArray("productDutyList"), ProductDuty.class);
      

    重点发现

    使用Json将字符串转换成实体类时,它会将所有的整数都变成浮点型,即所有的整数会加上’.0’,会导致后台判断出错,所以使用json的时候请格外注意,除此区别,没有复杂对象封装时,两者的转换效果是一样的

    展开全文
  • Gson使用方法

    2015-08-30 02:21:28
    Gson

    对于json数据,我们需要进行解析并封装为对象,Gson只需要传入空对象(包含所有字段),就可以将json字符串转化为modal,同时,modal也可以通过Gson转变为json数据。

    1、json转对象:

    该方法通过Xutils从服务器端获取数据并解析封装为对象:其中orderList为集合,对象ListView中adapter的数据。

    private void getDataList() {
    
            datas = new ArrayList<OrderItem>();
            RequestParams params = new RequestParams();
            params.addHeader("Authorization", "Bearer " + Constants.access_token);
            HttpUtils httpUtils = new HttpUtils();
            httpUtils.send(HttpRequest.HttpMethod.GET, Constants.baseURL
                    + "farmers/" + Constants.userID + "/orders?page=2", params,
                    new RequestCallBack<String>() {
    
                        @Override
                        public void onFailure(HttpException arg0, String arg1) {
                            Log.e("=====json 获取数据失败", arg1);
    
                        }
    
                        @Override
                        public void onSuccess(ResponseInfo<String> response) {
                            Log.e("我的订单=====json数据", response.result);
                            Gson gson = new Gson();
                            OrderList bean = gson.fromJson(response.result,
                                    OrderList.class);
    /*                      String json = gson.toJson(bean);
                            Log.e("我的订单=====转json ok", json);*/
                            datas = bean.content;
                            setAdapter();
                            Log.e("我的订单=====解析成功", response.result);
                        }
                    });
        }

    原json数据:

    {
        "content": [
            {
                "items": [
                    {
                        "serviceName": "葛淑英创建的"
                    }
                ],
                "orderNum": 2865023853,
                "putOrderTime": "2015-08-01 14:47:12",
                "state": "已取消"
            },
            {
                "items": [
                    {
                        "serviceName": "为黄氏而建"
                    }
                ],
                "orderNum": 3834137140,
                "price": "¥ 12300.00",
                "putOrderTime": "2015-08-01 14:44:09",
                "state": "已完成"
            },
            {
                "items": [
                    {
                        "serviceName": "为黄氏而建"
                    }
                ],
                "orderNum": 2930952581,
                "putOrderTime": "2015-08-01 13:58:35",
                "state": "已取消"
            },
            {
                "items": [
                    {
                        "serviceName": "播种"
                    },
                    {
                        "serviceName": "测土"
                    }
                ],
                "orderNum": 4828959701,
                "putOrderTime": "2015-08-01 13:03:33",
                "state": "已取消"
            },
            {
                "items": [
                    {
                        "serviceName": "播种"
                    }
                ],
                "orderNum": 4275681450,
                "price": "¥ 1230.00",
                "putOrderTime": "2015-06-24 10:48:18",
                "state": "已完成"
            }
        ],
        "first": false,
        "last": true,
        "number": 2,
        "numberOfElements": 5,
        "size": 10,
        "totalElements": 25,
        "totalPages": 3
    }

    对应的bean对象:

    orderList.java

    package com.irelint.stanleyagricultural.domain;
    
    import java.util.List;
    
    public class OrderList {
    
        public List<OrderItem> content;
    
        public class OrderItem{
            public List<OrderDes> items;
            public String orderNum;
            public String putOrderTime;
            public String state;
            public String price;
        }
        public class OrderDes{
            public String serviceName;
            public String imgUrl;
        }
    
    }
    

    如果json数据是集合而不是对象,则可以按如下方案(其中FarmerService封装的是集合中的对象):

    Type type = new TypeToken<LinkedList<FarmerService>>(){}.getType();
    Gson gson = new Gson();
    private LinkedList<FarmerService> farmerServices = gson.fromJson(response.result, type);
    展开全文
  • Google Gson 基本用法

    2017-01-04 20:36:31
    Google Gson 基本用法
  • 一个gson例子:java对象和json字符串之间相互转化
  • ORM+Volley+Gson用法

    2015-05-14 12:21:23
    本文件集成orm数据库、volley网络下载以及gson解析,用起来非常方便
  • GSON使用方法

    2018-05-23 13:08:52
    GSONbasicmaven&lt;dependency&gt; &lt;groupId&gt;com.google.code.gson&...gson&lt;/artifactId&gt; &lt;version&gt;2.6.2&lt;/version&gt; &lt;/depen
  • gson用法

    2019-10-02 02:19:27
    gson用法 转载于:https://www.cnblogs.com/huzi007/p/7795476.html
  • 简单GSON用法示例

    2016-12-18 17:32:44
    GSON是由Google开发的Java API,用于在Java对象和JSON对象之间进行...第二篇文章[todo]提供了更多使用GSON反序列化器(deserializer)的例子(JSON转Java),第三篇文章[todo]提供了更多关于GSON序列化器的例子(Java转
  • GSON是Google制作的一个可以让Java对象与JSON互相转换的类库,下面我们就来看一下Java的JSON转换库GSON的基本使用方法示例:
  • 目前网络上有很多接口是Json形式的,Gson是谷歌开源的Json解析库,可以方便的将Java对象转换成Json字符串,也可以方便的将Json字符串转换成Java对象。 OrderDTO.java @Data public class OrderDTO { /** 订单id...
  • Gson用法总结

    2018-04-23 14:23:05
    首先注入Gson的依赖 &lt;dependency&gt; &lt;groupId&gt;com.google.code.gson&lt;/groupId&gt; &lt;artifactId&gt;gson&lt;/artifactId&gt; &lt;version&gt;...
  • gson 的基本用法

    千次阅读 2018-04-26 10:46:16
    Gson的基本用法: 1、toJson 将object转化为json字符串 将此实体类转化为json字符串 class Persion{ public Persion(String name, int age) { this.name = name; this.age = age; } priva...
  • gson使用方法

    2013-08-23 16:53:22
    可以看到上面的代码使用了TypeToken,它是gson提供的数据类型转换器,可以支持各种数据集合类型转换。 转载地址: http://www.cnblogs.com/chenlhuaf/archive/2011/05/01/gson_test.html      ...
  • 浅谈Fastjson和Gson用法

    2021-08-05 19:57:31
    JSON类型为后端开发常用的数据格式,但目前Java官方没有提供格式方式,现在两种常用的类型为:阿里的Fastjson 和谷歌的Gson,以下简单介绍两种类型使用方法Gson: 一、将对象转换为JSON字符串 1、引入jar包 2、在...
  • Gson用法

    2015-03-29 23:08:33
    gson和其他现有java json类库最大的不同时gson需要序列化得实体类不需要使用annotation来标识需要序列化得字段,同时gson又可以通过使用annotation来灵活配置需要序列化的字段。 下面是一个简单的例子: Person...
  • // AAA // TypeToken 的构造方法是protected修饰的,所以上面才会写成new TypeToken>() {}.getType() 而不是 new TypeToken>().getType() 序列化:生成Json Gson gson = new Gson(); // 一般对象 TradeInfo trade ...
  • 关于Gson的一些使用方法总结

    千次阅读 2018-07-09 16:55:42
    1. 基本使用方法[fromJson/toJson] 将字符串解析成相应的对象 or 将对象Json化 这个应该是最常用的吧 Gson gson = new Gson(); String result = gson.fromJson(&amp;amp;quot;str&amp;amp;quot;,String....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,425
精华内容 14,970
关键字:

gson用法