您的位置:首页 > Web前端 > JavaScript

解析Json——Json类的静态方法

2015-07-01 00:00 706 查看
要使用bantouyan-json库解析Json数据,可以使用类Json。类Json是JsonArray、JsonObject和JsonPrimitive的基类,它有四个静态方法用于解析Json数据,这四个方法分别是parseJsonText、parseJsonReader、parseJavaMap、parseJavaCollection,下面依次介绍。

一、parseJsonText

要将一个表示Json文本的字符串解析成一个Json实例,就要调用方法Json类的静态方法parseJsonText,示例代码如下:

Java代码

import com.bantouyan.json.JsonObject;

public class TestBtyJson
{
public static void main(String[] args)
{
String jsonText = "{a: \"AA\", b: \"BB\", c: 23, d: true, e: null}";
JsonObject jobj = (JsonObject)Json.parseJsonText(jsonText);
System.out.println(jobj.getString("b"));
}
}
//输出: BB

parseJsonText返回一个Json类实例,但在实际使用过程中,我们更常使用的类是JsonArray和JsonObject,你可以用instanceof操作符或者Json类的实例方法getType来确定返回实例的类型。通常情况下,我们知道所解析的字符串内的Json文本到底是表示JsonArray还是JsonObject,即我们知道返回的Json实例的类型,所以我们可以直接使用强制类型转换。

如果我们传给方法parseJsonText的文本既不能表示成一个JsonArray,也不能表示成一个JsonObject,那么这个方法将抛出一个JsonException异常。这是一个runtimeException,没有必要时可以不予捕获,如果你不能保证所解析的Json文本格式正确,那么最好捕获这个异常并加以处理。捕获异常的示例代码如下:

Java代码

import com.bantouyan.json.*;

public class TestBtyJson
{
public static void main(String[] args)
{
String jsonText = "{a \"AA\", b: \"BB\", c: 23, d: true, e: null}";
JsonObject jobj = null;
try
{
jobj = (JsonObject)Json.parseJsonText(jsonText);
}
catch (JsonException e)
{
System.out.println(e.getMessage());
}
}
}
//输出: Non-blank character found at position 3 before ':'.

这个例子中Json Object的第一个子元素的Name与Value之间少了分隔符“:”,导致抛出异常JsonException,异常的Message解释了出现异常的原因:在“:”之前发现了非空白字符。

二、parseJsonReader

如果待解析的文本来自一个Reader对象,那么可以调用Json类的静态方法parseJsonReader,这个方法除了会抛出JsonException异常外,还会抛出IOException异常。示例代码如下:

Java代码

import java.io.IOException;
import com.bantouyan.json.*;

public class TestBtyJson
{
public static void main(String[] args)
{
Reader reader = new ......
JsonObject jobj = null;
try
{
jobj = (JsonObject)Json.parseJsonReader(reader);
}
catch (IOException e)
{
e.printStackTrace();
}
catch (JsonException e)
{
System.out.println(e.getMessage());
}
}
}

parserJsonReader要求被解析的JsonReader内包含一个完整的Json字符串,不允许Json字符串前后有其他非空白内容,否则会抛出异常,而且,读取Reader导致的异常IOException必须在代码中予以处理。

三、parseJavaCollection

如果要将一个Java Collection对象转换为一个JsonArray实例,就要调用方法parseJavaCollection,但要保证Collection对象内部没有循环引用并且所有的子元素都能解析,否则会抛出JsonException异常。示例代码如下:

Java代码

import java.util.*;
import com.bantouyan.json.*;

public class TestBtyJson
{
public static void main(String[] args)
{
ArrayList<Object> list = new ArrayList<Object>();
//list.add(list);
//list.add(new Timer());
JsonArray jary = null;
try
{
jary = Json.parseJavaCollection(list);
}
catch (JsonException e)
{
System.out.println(e.getMessage());
}
}
}
//(第一行注释)输出:Java colloection is referenced again.
//(第二行注释)输出:Cannot parse value: java.util.Timer@60aeb0 to json instance.

例子中的ArrayList经过解析后将得到一个空的JsonArray实例。如果把代码中的第一行注释去掉,那么将抛出由循环引用导致的异常,如果把第二行注释去掉,那么将抛出由无法解析导致的异常。

四、parseJavaMap

parseJavaMap与parseJavaCollection相似,只是把一个Java Map对象解析成JsonObject实例,同样要求Map对象内部没有循环引用并且所有的元素都能解析,否则会抛出JsonException异常。示例代码如下:

Java代码

import java.util.*;
import com.bantouyan.json.*;

public class TestBtyJson
{
public static void main(String[] args)
{
HashMap<Object, Object> map = new HashMap<Object, Object>();
//map.put("self", map);
//map.put("a", new Timer());
JsonObject jobj = null;
try
{
jobj = Json.parseJavaMap(map);
}
catch (JsonException e)
{
System.out.println(e.getMessage());
}
}
}
//(第一行注释)输出:Java map is referenced again.
//(第二行注释)输出:Cannot parse value: java.util.Timer@60aeb0 to json instance.

这个例子与上一个类似,map对象解析后得到一个空的JsonObject实例,如果把代码中的第一行注释去掉,那么将抛出由循环引用导致的异常,如果把第二行注释去掉,那么将抛出由无法解析导致的异常。

五、JsonParser

默认情况下,parseJavaCollection与parseJavaMap只能处理一些简单的类型,如String、Number、Boolean等,如果要处理普通的Java类,就要为这些类实现Jsonable接口。但是这有局限性,例如我们要处理的类不是我们自己编写的而是来自其他包,这时候再使用Jsonable就很不方便。为了解决这种不便,bantouyan-json库还提供了另外一个接口JsonParser,该接口用在parseJavaCollection与parseJavaMap的重载版本parseJavaCollection(Collection, Jsonparser)与parseJavaMap(Map, Jsonparser)中。

Jsonparser有四个方法,canToName用于判断Java对象是否可以转换为JsonObject子元素的Name,changToName用于将Java对象转换为JsonObject子元素的Name,canToJson用于判断Java对象是否可以转换为Json实例,changeToJson用于将Java对象转换为Json实例。需要注意的是,只有通过canToJson(canToName)的Java对象,即返回true,才会在parseJavaCollection(Collection, Jsonparser)与parseJavaMap(Map, Jsonparser)中用changeToJson(changeToName)处理,如果通不过,即返回false,则按默认规则处理。

下面是一个例子:

Java代码

import com.bantouyan.json.*;

public class StringParser implements JsonParser
{
public boolean canToName(Object obj)
{
if(obj instanceof String)
return ((String)obj).startsWith("*");
else
return false;
}

public String changeToName(Object obj) throws JsonException
{
String str = (String)obj;
return "Name_" + str.substring(1);
}

public boolean canToJson(Object obj)
{
if(obj instanceof String)
return ((String)obj).startsWith("#");
else
return false;
}

public Json changeToJson(Object obj) throws JsonException
{
String str = (String)obj;
return new JsonPrimitive("Value_" + str.substring(1));
}
}


Java代码

import java.util.*;
import com.bantouyan.json.*;

public class TestBtyJson
{
public static void main(String[] args)
{
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put("na", "#va");
map.put("*b", "vb");
ArrayList<Object> list = new ArrayList<Object>();
list.add("eA");
list.add("#eb");
list.add(map);

JsonParser parser = new StringParser();
JsonArray jaryA = Json.parseJavaCollection(list);
System.out.println(jaryA);
JsonArray jaryB = Json.parseJavaCollection(list, parser);
System.out.println(jaryB);
}
}
//输出:["eA","#eb",{"*b":"vb","na":"#va"}]
//输出:["eA","Value_eb",{"Name_b":"vb","na":"Value_va"}]


例子中的JsonParse对于以*开头的Name,会转换为以Name_开头, 对于以#开头的Value,会转换为以Value_开头的字符串型Json实例。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Json