2021SC@SDUSC
12.Groovy重要类源码
今天要分析的主要代码是在groovy包下的,我们由易到难依次来分析一下这个包中的源码。这个包下大家如果打开源码的话,可以看到,其中的包非常的多,但大部分都是我们在写gradle或者groovy脚本时用不到的,我们最常用到的包就是:json xml lang这三个包,我们重点分析这三个包下的一些核心类,来看一下他们的作用。
第一部分:json package这个package大家一看就可以知道,是提供对json格式的文件,数据等进行一些操作的,比java中确实要强大的多。package中最核心的类又是:JsonSlurper,JsonBuilder这两个类,通过类的名字我们也能够知道,一个类是用来将json格式的数据转化为Object,后一个是将Object转化为json串,下面我们首先来看一下JsonSluper的核心代码。
public class JsonSlurper {
private int maxSizeForInMemory = 2000000;
private boolean chop = false;
private boolean lazyChop = true;
private boolean checkDates = true;
private JsonParserType type;
public JsonSlurper() {
this.type = JsonParserType.CHAR_BUFFER;
}
public Object parseText(String text) {
if(text != null && !"".equals(text)) {
return this.createParser().parse(text);
} else {
throw new IllegalArgumentException("Text must not be null or empty");
}
}
public Object parse(Reader reader) {
if(reader == null) {
throw new IllegalArgumentException("Reader must not be null");
} else {
JsonParser parser = this.createParser();
Object content = parser.parse(reader);
return content;
}
}
public Object parse(InputStream inputStream) {
if(inputStream == null) {
throw new IllegalArgumentException("inputStream must not be null");
} else {
JsonParser parser = this.createParser();
Object content = parser.parse(inputStream);
return content;
}
}
}
private JsonParser createParser() {
switch(null.$SwitchMap$groovy$json$JsonParserType[this.type.ordinal()]) {
case 1:
return new JsonParserLax(false, this.chop, this.lazyChop, this.checkDates);
case 2:
return new JsonParserCharArray();
case 3:
return new JsonParserUsingCharacterSource();
case 4:
return new JsonFastParser(false, this.chop, this.lazyChop, this.checkDates);
default:
return new JsonParserCharArray();
}
}
好,到这里,我们就不再分析他具体的各个解析器是如何去处理的了,大家有兴趣的可以自己去看源码,对我们开发人员来说,就重要的就是这个入口类,JsonSlurper。好下面我简单贴一下这个类的最常见的用法:
def getNetworkData(String url) {
def connection = new URL(url).openConnection()
connection.setRequestMethod('GET')
connection.connect()
def response = connection.content.text
def jsonSluper = new JsonSlurper()
return jsonSluper.parseText(response)
}
以上代码也很简单,就是通过http请求拿到服务端的json数据,然后通过JsonSlurper来解析成Object供我们去更方便的使用。我们系列文章中的示例代码均来自于我的gradle实战课程,大家可以去系统的学习一下。所以在groovy中,我们就不再需要引入一些第三方的json解析库了。非常方便。下面我们再来看一下另一个JsonBuilder类,核心代码如下:
public class JsonBuilder extends GroovyObjectSupport implements Writable {
private Object content;
public JsonBuilder() {
}
public JsonBuilder(Object content) {
this.content = content;
}
public String toString() {
return JsonOutput.toJson(this.content);
}
public String toPrettyString() {
return JsonOutput.prettyPrint(this.toString());
}
上面,我只列出了最核心和常用到的两个方法,我们可以看到,其实最终调用的都是JsonOutput类中对应的方法。下面我们就把JsonOutput中的核心方法列出:
private static void writeObject(Object object, CharBuf buffer) {
其实,如果大家看过Java中的gson等库以后,他们基本都是这样的处理方式基本。 接着,我们来看一下xml包,这个package包中最重要的类是:MarkupBuilder.从类名我们可以知道,这个类是用来生成标记格式类型数据,例如:XML,HTML等格式的数据。 这个类的源码我们就不看了,因为他依赖了groovy中的元编程,我们最后会讲groovy的元编程,知道了源编程以后,你就会明白MarkupBuilder的原理。下面我们简单看一下这个类的用法,也非常的简单,代码如下:
def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw)
def langs = new Langs()
xmlBuilder.langs(type: langs.type, count: langs.count,mainstream: langs.mainstream) {
langs.languages.each { lang ->
language(flavor: lang.flavor,
version: lang.version, lang.value)
}
}
println sw
class Langs {
String type = 'current'
int count = 3
boolean mainstream = true
def languages = [
new Language(flavor: 'static',
version: '1.5', value: 'Java'),
new Language(flavor: 'dynamic',
version: '1.3', value: 'Groovy'),
new Language(flavor: 'dynamic',
version: '1.6', value: 'JavaScript')
]
}
class Language {
String flavor
String version
String value
}
下面,我们来稍微解释一下这块代码,最下面的两个实体类代表我们要动态写到xml格式中的数据,核心方法就是这段:
xmlBuilder.langs(type: langs.type, count: langs.count,mainstream: langs.mainstream) {
langs.languages.each { lang ->
language(flavor: lang.flavor,
version: lang.version, lang.value)
}
}
经过上面的代码,我们最终生成的xml格式的数据就是:
<langs type='current' count='3' mainstream='true'>
<language flavor='static' version='1.5'>Java</language>
<language flavor='dynamic' version='1.6.0'>Groovy</language>
<language flavor='dynamic' version='1.9'>JavaScript</language>
</langs>
|