文章目录
0.前言
遇到一个场景使用gjson解析无固定模板的json串变成TreeMap时value值出现两个双引号
0.1解决方法
如果直接用 JsonObject.toSring或者jo.get(“name”).toString的话,取出的值会有双引号,直接getAsString就没有双引号啦
1.gson的使用
1.1对象转json
gson的maven
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
</dependency>
准备封装的对象
package learn.JSON.gsonLearn;
import java.math.BigDecimal;
/**
* @author WangWenLei
* @DATE: 2021/6/21
**/
public class Student {
private String name;
private int age;
private char sex;
private float height;
private BigDecimal money;
public Student(String name, int age, char sex, float height, BigDecimal money) {
this.name = name;
this.age = age;
this.sex = sex;
this.height = height;
this.money = money;
}
// getter/setter
序列化
package learn.JSON.gsonLearn;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.math.BigDecimal;
/**
* @author WangWenLei
* @DATE: 2021/6/21
**/
public class Main {
public static void main(String[] args) {
Student student = new Student("wwl",25,'y',170.2F,BigDecimal.valueOf(20210421));
// 构建
GsonBuilder gsonBuilder = new GsonBuilder();
// 创建Gson对象
Gson gson = gsonBuilder.create();
// 序列化
String s = gson.toJson(student);
System.out.println(s);
}
}
效果
1.2 json转对象
package learn.JSON.gsonLearn;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author WangWenLei
* @DATE: 2021/6/22
**/
public class JsonToObj {
public static void main(String[] args) {
String json = "{\"name\":\"wwl\",\"age\":25," +
"\"sex\":\"y\",\"height\":170.2,\"money\":20210421}";
Gson gson = new GsonBuilder().create();
// 单个class的解析
Student student = gson.fromJson(json, Student.class);
System.out.println(student.toString());
// 简单数组的解析
String json1 = "[\"Android\",\"Java\",\"PHP\"]";
String[] strings = gson.fromJson(json1, String[].class);
Arrays.stream(strings).forEach(item -> System.out.println(item + " "));
System.out.println();
//对于Java来说List<String> 和List<User> 这俩个的字节码文件
// 只一个那就是List.class,这是Java泛型使用时要注意的问题 泛型擦除
//Gson为我们提供了TypeToken来实现对泛型的支持,所以当我们
// 希望使用将以上的数据解析为List<String>时需要这样写
List<String> o = gson.fromJson(json1, new TypeToken<List<String>>() {
}.getType());
o.forEach(item -> System.out.print(item + " "));
System.out.println();
// 对于对象
String jsonArray = "[{\"name\":\"wwl1\",\"age\":25,\"sex\":\"y\"," +
"\"height\":170.2,\"money\":20210421},{\"name\":\"wwl2\"," +
"\"age\":25,\"sex\":\"y\",\"height\":170.2,\"money\":20210421}]";
List<Student> list = gson.fromJson(jsonArray,new TypeToken<List<Student>>(){
}.getType());
System.out.println(list.toString());
}
}
1.3属性重命名 @SerializedName 注解的使用
对接不同系统时经常会因为不同的参数命名方法而序列化成不同的名称,在接收时会造成不和谐如:
期望接收json格式:
{
"name":"wwl1","age":25,"sex":"y","height":170.2,"money":20210421}
实际接收参数
{
"NAME":"wwl1","AGE":25,"SEX":"y","HEIGHT":170.2,"MONEY":20210421}
我们知道Gson在序列化和反序列化时需要使用反射
@SerializedName("NAME")
private String name;
@SerializedName("AGE")
private int age;
@SerializedName("SEX")
private char sex;
@SerializedName("HEIGHT")
private float height;
@SerializedName("MONEY")
private BigDecimal money;
这样设置后序列化的样子,也得使用这个进行反序列化
{
"NAME":"wwl1","AGE":25,"SEX":"y","HEIGHT":170.2,"MONEY":20210421}
2.4版本后 @SerializedName注解除了了value属性还有alternate属性(反序列化时字段的替代名称)接收一个String数组
当上面的三个属性(email_address、email、emailAddress)都中出现任意一个时均可以得到正确的结果。
1.当多种情况同时出时,以最后一个出现的值为准。
2.value值与alternate里的值不能重复
@SerializedName(value = "name",alternate = {
"NAME","name1"})
private String name;
name1被反序列化成name
String json = "{\"name1\":\"wwl1\",\"AGE\":25" +
",\"SEX\":\"y\",\"HEIGHT\":170.2,\"MONEY\":20210421}";
Gson gson = new GsonBuilder().create();
// 单个class的解析
Student student = gson.fromJson(json, Student.class);
System.out.println(student.toString());
1.4 json序列化成map
先得到一个json串再反序列化成map
结果如下:
代码如下:
package learn.JSON.gsonLearn;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.Map;
import java.util.TreeMap;
/**
* @author WangWenLei
* @DATE: 2021/6/22
**/
public class JsonToMap {
public static void main(String[] args) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name","wwl");
jsonObject.addProperty("age","25");
jsonObject.addProperty("height","170.2");
jsonObject.addProperty("data","170.2");
JsonObject jsonObject1 = new JsonObject();
jsonObject1.addProperty("key1","value1");
jsonObject1.addProperty("key2","value2");
jsonObject.add("data", jsonObject1);
Gson gson = new GsonBuilder().create();
String json = gson.toJson(jsonObject);
System.out.println(json);
Map<String, Object> o = gson.fromJson(json, new TypeToken<TreeMap<String, Object>>() {
}.getType());
System.out.println(o.toString());
System.out.println();
}
}
2. Gson的配置
// 当字段值为空或null时,依然对该字段进行转换
.serializeNulls()
// json宽松
.setLenient()
//对结果进行格式化,增加换行,变得更好看
.setPrettyPrinting()
//时间转化为特定格式
.setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")
//不对没有用@Expose注解的属性进行操作
.excludeFieldsWithoutExposeAnnotation()
//当Map的key为复杂对象时,需要开启该方法
.enableComplexMapKeySerialization()
//防止特殊字符出现乱码。默认是GSON把HTML,转义用的
.disableHtmlEscaping()
//为某特定对象设置固定的序列或反序列方式,自定义Adapter需实现JsonSerializer或者JsonDeserializer接口
.registerTypeAdapter(Student.class,new StudentAdapter())
文文的博客~