package javax.json.stream;
import java.io.Closeable;
import java.math.BigDecimal;
/**
* 目的:流方式读取JSON数据
*
* <p>以流的方式提供一个向前只读来访问JSON数据。这是最有效读取JSON数据的方法。
* {@link javax.json.Json}含有能够解析来自输入源(如:InputStream或Reader)数据的方法。
*
* <p>以下示例说明一个字符串解析成空的JSON数组:
* JsonParser parser = Json.createParser(new StringReader("[]"));
*
* <p>{@link JsonParserFactory}创建JsonParser实例:
* JsonParserFactory factory = Json.createParserFactory();
* JsonParser parser1 = factory.createParser(...);
* JsonParser parser2 = factory.createParser(...);
*
* <p>JsonParser能解析JSON使用的编程模型。这个模型中,客户机能控制线程并调用{@code next()}
* 方法来推进解析器处理每个元素的下一个状态。解析器能生成以下事件:
* START_OBJECT,END_OBJECT,START_ARRAY,END_ARRAY,KEY_NAME,
* VALUE_STRING,VALUE_NUMBER,VALUE_TRUE,VALUE_FALSE,VALUE_NULL。
*
* <p>例如,对于一个空JSON对象({ })。当解析器第一次调用next(),将生成一个START_OBJECT事件。
* 第二次调用next(),将生成一个END_OBJECT事件。如以下代码所示:
* Event event = parser.next(); // START_OBJECT
* event = parser.next(); // END_OBJECT
*
* <p>例如:以下的JSON示例:
* {
* "firstName": "John", "lastName": "Smith", "age": 25,
* "phoneNumber": [
* { "type": "home", "number": "212 555-1234" },
* { "type": "fax", "number": "646 555-4567" }
* ]
* }
* 对应事件:
* {START_OBJECT
* "firstName"KEY_NAME: "John"VALUE_STRING,
* "lastName"KEY_NAME: "Smith"VALUE_STRING,
* "age"KEY_NAME: 25VALUE_NUMBER,
* "phoneNumber"KEY_NAME :
* [START_ARRAY
* {START_OBJECT
* "type"KEY_NAME: "home"VALUE_STRING,
* "number"KEY_NAME: "212 555-1234"VALUE_STRING
* }END_OBJECT,
* {START_OBJECT
* "type"KEY_NAME: "fax"VALUE_STRING,
* "number"KEY_NAME: "646 555-4567"VALUE_STRING
* }END_OBJECT
* ]END_ARRAY
* }END_OBJECT
*
* <p>使用next()和hasNext()可以迭代解析JSON数据事件,JsonParser对象能够获取当前解析器状态
* 的值。例如,以下代码显示怎么获取“John”值:
* Event event = parser.next(); // START_OBJECT
* event = parser.next(); // KEY_NAME
* event = parser.next(); // VALUE_STRING
* parser.getString(); // "John"
* @author TCM
* @create 2017年11月7日上午11:08:52
* @see javax.json.Json
* @see JsonParserFactory
*/
public interface JsonParser extends /*Auto*/Closeable {
//事件
enum Event {
START_ARRAY, //JSON数组的开始,解析器位置在'['之后
START_OBJECT,//JSON对象的开始,解析器位置在'{'之后
KEY_NAME, //JSON对象的name值,getString()获取,解析器位置在KEY_NAME之后
VALUE_STRING,//JSON对象的value值,getString()获取,解析器位置在VALUE_STRING之后
VALUE_NUMBER,//JSON对象或数组的value值,getInt()...获取,位置在VALUE_NUMBER之后
VALUE_TRUE, //JSON对象或数组的value值,位置在VALUE_TRUE之后
VALUE_FALSE, //JSON对象或数组的value值,位置在VALUE_FALSE之后
VALUE_NULL, //JSON对象或数组的value值,位置在VALUE_NULL之后
END_OBJECT, //JSON对象的结束,解析器位置在'}'之后
END_ARRAY //JSON数组的结束,解析器位置在']'之后
}
//解析器是否有一个事件
boolean hasNext();
//下一个解析状态的事件
Event next();
String getString();
boolean isIntegralNumber();
int getInt();
long getLong();
BigDecimal getBigDecimal();
//获取解析器当前状态的位置(输入源中的位置)
JsonLocation getLocation();
//关闭解析器并释放资源
@Override
void close();
}
package javax.json.stream;
import javax.json.JsonArray;
import javax.json.JsonObject;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.Map;
/**
* 目的:工厂创建JsonParser实例
*
* <p>工厂创建{@link JsonParser}实例。若果一个工厂实例被配置信息配置,则该配置应用到
* 所有创建JsonParser实例中。
*
* <p>{@link javax.json.Json Json}类也提供创建JsonParser实例的方法,但是
* 使用工厂方法创建多个JsonParser实例是最好的,如下所示:
* JsonParserFactory factory = Json.createParserFactory();
* JsonParser parser1 = factory.createParser(...);
* JsonParser parser2 = factory.createParser(...);
*
* <p>该类所有的方法都是线程安全的,使用在多并发线程。
* @author TCM
* @create 2017年11月7日下午1:56:17
*/
public interface JsonParserFactory {
JsonParser createParser(Reader reader);
JsonParser createParser(InputStream in);
JsonParser createParser(InputStream in, Charset charset);
JsonParser createParser(JsonObject obj);
JsonParser createParser(JsonArray array);
//获取配置属性的map
Map<String, ?> getConfigInUse();
}
package javax.json.stream;
/**
* 目的:JSON事件的位置信息
*
* <p>提供一个JSON事件在输入源中的位置信息。{@code JsonLocation}信息用来识别错误的
* JSON,或是更高的框架使用这些信息能够知道处理位置。
*
* <p>{@code JsonLocation}提供这些信息是可选的。例如,可以提供行号。另外,输入源中
* 没有任何位置信息。例如:JsonParser从输入源解析成JsonArray,所有的方法返回-1。
* @author TCM
* @create 2017年11月7日上午10:36:24
* @see JsonParser
* @see JsonParsingException
*/
public interface JsonLocation {
//当前JSON事件在输入源中的行号(若没有行号,则返回-1)
long getLineNumber();
//当前JSON事件在输入源中的列号(若没有列号,则返回-1)
long getColumnNumber();
/**
* 返回输入源中的流的位置指向。如果输入源是文件或字节流,那么在流中的位置是以字节为指向。
* 但是输入源是字符流,那么字符的位置是指向。若没有偏向,则返回-1。
* @return 流中的位置偏向(指针位置),没有则返回-1
*/
long getStreamOffset();
}