-
Notifications
You must be signed in to change notification settings - Fork 1
DemoJSON
JSON 是JavaScript Object Notation的缩写,用轻量级的文本形式描述对象的结构与取值。
一个最典型的JSON文本类似于{"id":1,“name”:"King"}
JSON在Java中的实现继承了Map接口,并且可以解析/生成JSON文本。
如果字符串变量String str的值为{"id":1,“name”:"King"},可以通过JSON.Parse(CharSequence)方法来解析该字符串,以得到JSON对象。
// 解析JSON文本
JSON json = JSON.Parse(str);
通过调用JSON对象的toString()方法,可以将JSON对象还原成JSON文本。
// 输出JSON文本 {"id":1,"name":"King"}
System.out.println("输出JSON文本:" + json.toString());
如果想格式化JSON文本,则可以调用toString(int)方法,其参数表示缩进字符的个数,通常指定为0。
/* 以0缩进字符输出JSON文本
{
"id":1,
"name":"King"
}
*/
System.out.println("格式化输出文本:" + json.toString(0));
JSON对象的attr(String)方法用以读取某个键对应的属性值(类似于Map的get方法)。
System.out.println("读取id属性:" + json.attr("id"));
设置属性的方法则为attr(String,Object),第一个参数为键名,第二个为属性值(类似于Map的put方法)。
json.attr("id", 2);
System.out.println("设置id属性后:" + json.attr("id"));
attr(String,Object)方法支持链式调用。
System.out.println("链式调用attr方法:" + json.attr("id", 3).attr("name", "Quene").toString(0));
值得注意的是,attr系列方法本质上就是基于Map的get/put方法。但考虑到JSON对象之间的引用特性,而这种情况下,get/put方法操作的是“引用”,而非被引用的值本身,因此会导致意想不到的问题,而attr系列方法则始终操作的是值本身。类似地,entrySet()方法返回的键值对中的值也未必是值本身,因此建议使用pairs()方法来遍历键值对。
for(Pair pair: json.pairs()) {
System.out.println(pair.getKey() + "\t" + pair.getValue());
}
attr还有一个语法糖,那就是会将Map(或者Iterable)值自动转换为JSON(或者JSAN)存放。
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("fst", 1);
map.put("sec", 2);
json.attr("map", map);
System.out.println("设置map属性:" + json.toString(0));
此外val方法也同样能获取属性值。
System.out.println("另一种读取属性的方法:" + json.val("id"));
虽然该方法与attr(String)别无二致,但val(String,Object)则允许为null值设置默认值。
// 带默认值的读取方式,如果键对应的值为null,则返回默认值。
System.out.println("带默认值读取type属性:" + json.val("type", "default"));
attr和val系列方法还对Java基本类型进行了支持,当不能进行正确转换时,attr系列方法返回null,val系列方法则可以通过设定额外的默认值防止返回null。
Integer id = json.attrInteger("id");
System.out.println("以整数类型进行读取:" + id);
id = json.attrInteger("map");
System.out.println("对于不能转换类型的返回null:" + id);
id = json.valInteger("map", 123);
System.out.println("对于不能转换类型的设置默认值:" + id);
JSON可以通过反射特性读取POJO,POJO中所有通过getter开放的属性都可以被读取。
假如有下面的POJO类
public class DemoPOJO { private int id; private String name; private double value; private Map<String, Object> dict; private float income;
public DemoPOJO() { this.id = 1; this.name = "Joke"; this.value = 1.23; this.dict = new LinkedHashMap<String, Object>(); this.dict.put("one", 1); this.dict.put("two", 2); this.income = 100.1f; }
// JSON在反射时,会将Map类对象反射为JSON。 public Map<String, Object> getDict() { return dict; }
public int getId() { return id; }
// 不开放此属性,JSON将不会反射该数据。 protected float getIncome() { return income; }
public String getName() { return name; }
public double getValue() { return value; } }
DemoPOJO pojo = new DemoPOJO();
JSON.Reflect(Object)方法用来反射读取POJO对象。
这里,由于income属性没有开放对应的getter方法,故不会被反射读取。
JSON reflect = JSON.Reflect(pojo);
System.out.println("反射读取pojo:" + reflect.toString(0));
当然也可以反射读取部分属性,这里仍然不会反射到income数据。
reflect = JSON.Reflect(pojo, "name", "value", "income");
System.out.println("反射读取部分属性:" + reflect.toString(0));
反射部分属性,并对属性名进行映射。
Map<String, String> memMap = new LinkedHashMap<String, String>();
memMap.put("名称", "name");
memMap.put("数值", "value");
reflect = JSON.Reflect(pojo, memMap);
System.out.println("反射读取并映射部分属性:" + reflect.toString(0));
对于后续增加的数据,可以通过预先对JSON对象指定反射模板来进行统一反射。
reflect = new JSON().templateJSAN(DemoPOJO.class, "name", "id", "value");
reflect.attr("demo", pojo);
System.out.println("通过模板对后续加入的数据进行反射:" + reflect.toString(0));