概述 Groovy是一种基于JVM的面向对象语言,如果不声明public/private等访问权限的话,Groovy中类及其变量默认都是public的。
Groovy中有以下特点:
同时支持静态和动态类型
支持运算符重载
对正则表达式的本地支持
可以使用现有的Java库及Java语法
不需要分号
可省略return关键字,默认用最后一个表达式为返回
使用命名的参数初始化beans和默认的构造器:new Server(name: "Obelix", cluster: aCluster)
Groovy里的is()
方法等同于Java里的==
,Groovy中的==
是更智能的equals()
在同一个bean中使用with()来重复某一个操作: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 server.name = application.name server.status = status server.sessionCount = 3 server.start() server.stop() server.with { name = application.name status = status sessionCount = 3 start() stop() }
基本语法 1 2 3 4 5 class Test { static void main(String[] args) { println('Hello World.' ) } }
在Groovy中下列包是默认导入的:
1 2 3 4 5 6 7 8 9 10 import java.lang.* import java.util.* import java.io.* import java.net.* import groovy.lang.* import groovy.util.* import java.math.BigInteger import java.math.BigDecimal
Groovy中使用def来定义变量。
数据类型 内置数据类型
byte -这是用来表示字节值。例如2。
short -这是用来表示一个短整型。例如10。
int -这是用来表示整数。例如1234。
long -这是用来表示一个长整型。例如10000090。
float -这是用来表示32位浮点数。例如12.34。
double -这是用来表示64位浮点数,这些数字是有时可能需要的更长的十进制数表示。例如12.3456565。
char -这定义了单个字符文字。例如“A”。
Boolean -这表示一个布尔值,可以是true或false。
String -这些是以字符串的形式表示的文本。
Groovy提供了多种表示String字面量的方法。 Groovy中的字符串可以用单引号(’),双引号(“)或三引号(”“”)括起来。此外,由三重引号括起来的Groovy字符串可以跨越多行。
Groovy中的字符串是字符的有序序列,字符串索引从零开始,还允许负索引从字符串的末尾开始计数。
1 2 3 4 5 6 7 8 9 10 11 class Example { static void main(String[] args) { String sample = "Hello world" ; println(sample[4 ]); println(sample[-1 ]); println(sample[1. .2 ]); println(sample[4. .2 ]); } }
对象类型(包装器类型)
java.lang.Byte
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float
java.lang.Double
父类为Number
Groovy中的变量可以通过两种方式定义: 使用数据类型的语法,或者使用def关键字。对于变量定义,必须明确提供类型名称或在替换中使用“def”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Example { static void main(String[] args) { int x = 5 ; long y = 100 L; float a = 10.56 f; double b = 10.5e40 ; BigInteger bi = 30 g; BigDecimal bd = 3.5 g; println(x); println(y); println(a); println(b); println(bi); println(bd); } }
运算符 Groovy语言支持正常的算术运算符任何语言。
范围运算符:
1 2 def range = 5. .10 ;println(range.get(3 ))
范围由序列中的第一个和最后一个值表示,Range可以是包含或排除。包含范围包括从第一个到最后一个的所有值,而独占范围包括除最后一个之外的所有值。
1..10 - 包含范围的示例
1..<10 - 独占范围的示例
‘a’..’x’ - 范围也可以由字符组成
10..1 - 范围也可以按降序排列
‘x’..’a’ - 范围也可以由字符组成并按降序排列。
可通过list[index]方式访问。
方法
用法
contains()
检查范围是否包含特定值
get()
返回此范围中指定位置处的元素。
getFrom()
获得此范围的下限值。
getTo()
获得此范围的上限值。
isReverse()
这是一个反向的范围,反向迭代
size()
返回此范围的元素数。
subList()
返回此指定的fromIndex(包括)和toIndex(排除)之间的此范围部分的视图
循环
语句
描述
while
首先通过计算条件表达式(布尔值)来执行,如果结果为真,则执行while循环中的语句。
for
用于遍历一组值。
for-in
用于遍历一组值。
break
用于改变循环和switch语句内的控制流。
continue
补充了break语句。它的使用仅限于while和for循环。
方法 Groovy中的方法是使用返回类型或使用def关键字定义的。方法可以接收任意数量的参数。定义参数时,不必显式定义类型 ,可以给参数使用初始值。可以添加修饰符,如public,private和protected。默认情况下,如果未提供可见性修饰符,则该方法为public。
最简单的方法是没有参数的方法,如下所示:
1 2 3 4 5 6 7 8 9 10 class Example { static def DisplayName() { println("This is how methods work in groovy" ); println("This is an example of a simple method" ); } static void main(String[] args) { DisplayName(); } }
以下是使用参数的简单方法的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Example { static void sum(int a,int b) { int c = a+b; println(c); } static void sum(a, b) { int c = a + b; println(c); } static void main(String[] args) { sum(10 ,5 ); } }
Groovy中还有一个规定来指定方法中的参数的默认值。 如果没有值传递给参数的方法,则使用缺省值。 如果使用非默认和默认参数,则必须注意,默认参数应在参数列表的末尾定义。
以下是使用参数的简单方法的示例:
1 2 3 4 5 6 7 8 9 10 class Example { static void sum(int a, int b = 5 ) { int c = a + b; println(c); } static void main(String[] args) { sum(6 ); } }
I/O Groovy在使用I/O时提供了许多辅助方法,同时也可以使用Java原生IO类。
读取文件 以下示例将输出Groovy中的文本文件的所有行。方法eachLine内置在Groovy中的File类中,目的是确保文本文件的每一行都被读取。
1 2 3 4 5 6 7 8 9 import java.io.Fileclass Example { static void main(String[] args) { new File("E:/Example.txt" ).eachLine { line -> println "line : $line" ; } } }
如果要将文件的整个内容作为字符串获取,可以使用文件类的text属性,即:String s = file.text
。
写入文件 如果想写入文件,则需要使用Write类输出文本到一个文件中:
1 2 3 4 5 6 7 8 import java.io.File class Example { static void main(String[] args) { new File('E:/' ,'Example.txt' ).withWriter('utf-8' ) { writer -> writer.writeLine 'Hello World' } } }
获取文件的大小 如果要获取文件的大小,可以使用文件类的length属性来获取:
1 2 3 4 5 6 class Example { static void main(String[] args) { File file = new File("E:/Example.txt" ) println "The file ${file.absolutePath} has ${file.length()} bytes" } }
文件是否是目录 如果要查看路径是文件还是目录,可以使用File类的isFile和isDirectory选项:
1 2 3 4 5 6 7 class Example { static void main(String[] args) { def file = new File('E:/' ) println "File? ${file.isFile()}" println "Directory? ${file.isDirectory()}" } }
创建目录 如果要创建一个新目录,可以使用File类的mkdir函数:
1 2 3 4 5 6 class Example { static void main(String[] args) { def file = new File('E:/Directory' ) file.mkdir() } }
删除文件 如果要删除文件,可以使用File类的delete功能:
1 2 3 4 5 6 class Example { static void main(String[] args) { def file = new File('E:/Example.txt' ) file.delete() } }
复制文件 Groovy还提供将内容从一个文件复制到另一个文件的功能:
1 2 3 4 5 6 7 class Example { static void main(String[] args) { def src = new File("E:/Example.txt" ) def dst = new File("E:/Example1.txt" ) dst << src.text } }
获取目录内容 Groovy还提供了列出驱动器中的驱动器和文件的功能,以下示例显示如何使用File类的listRoots函数显示机器上的驱动器:
1 2 3 4 5 6 7 8 class Example { static void main(String[] args) { def rootFiles = new File("test" ).listRoots() rootFiles.each { file -> println file.absolutePath } } }
以下示例显示如何使用File类的eachFile函数列出特定目录中的文件:
1 2 3 4 5 6 7 class Example { static void main(String[] args) { new File("E:/Temp" ).eachFile() { file->println file.getAbsolutePath() } } }
如果要递归显示目录及其子目录中的所有文件,则可以使用File类的eachFileRecurse函数:
1 2 3 4 5 6 7 class Example { static void main(String[] args) { new File("E:/temp" ).eachFileRecurse() { file -> println file.getAbsolutePath() } } }
List
[11,12,13,14] - 整数值列表
[‘Angular’,’Groovy’,’Java’] - 字符串列表
[1,2,[3,4],5] - 嵌套列表
[‘Groovy’,21,2.11] - 异构的对象引用列表
[] - 空列表
可通过list[index]方式访问。
方法
用法
add()
将新值附加到此列表的末尾。
contains()
如果此列表包含指定的值,则返回true。
get()
返回此列表中指定位置的元素。
isEmpty()
如果此列表不包含元素,则返回true
minus()
创建一个由原始元素组成的新列表,而不是集合中指定的元素。
plus()
创建由原始元素和集合中指定的元素组成的新列表。
pop()
从此列表中删除最后一个项目
remove()
删除此列表中指定位置的元素。
reverse()
创建与原始列表的元素相反的新列表
size()
获取此列表中的元素数。
sort()
返回原始列表的排序副本。
多重赋值和多返回值:
1 2 3 4 5 6 7 def (a, b, c) = fun()def fun() { return [f1, f2, f3] }
Map
[‘TopicName’: ‘Lists’, ‘TopicName’: ‘Maps’] - 具有TopicName作为键的键值对的集合及其相应的值。
[:] - 空映射。
方法
用法
containsKey()
此映射是否包含此键
get()
查找此Map中的键并返回相应的值。如果此映射中没有键的条目,则返回null。
keySet()
获取此映射中的一组键。
put()
将指定的值与此映射中的指定键相关联。如果此映射先前包含此键的映射,则旧值将替换为指定的值。
size()
返回此地图中的键值映射的数量。
values()
返回此地图中包含的值的集合视图。
键可以是任意类型:
1 2 def m = [1 : 2 , 2 : 3 ]println(m.get(2 ))
Date 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Example { static void main(String[] args) { Date date = new Date(); System.out.println(date.toString()); } } -> output: Thu Dec 10 21 :31 :15 GST 2015 class Example { static void main(String[] args) { Date date = new Date(100 ); System.out.println(date.toString()); } } ->output: Thu Jan 01 04 :00 :00 GST 1970
下面是一些常用方法:
方法
作用
after()
测试此日期是否在指定日期之后。
equals()
比较两个日期的相等性。当且仅当参数不为null时,结果为true,并且是表示与该对象时间相同的时间点(毫秒)的Date对象。
compareTo()
比较两个日期的顺序。
toString()
将此Date对象转换为字符串
before()
测试此日期是否在指定日期之前。
getTime()
返回自此Date对象表示的1970年1月1日,00:00:00 GMT以来的毫秒数。
setTime()
设置此Date对象以表示一个时间点,即1970年1月1日00:00:00 GMT之后的时间毫秒。
regex Groovy使用〜“regex”表达式本地支持正则表达式,引号中包含的文本表示用于比较的表达式:
字符
说明
\
将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,”n”匹配字符”n”。”\n”匹配换行符。序列”\\“匹配”\“,”\(“匹配”(“。
^
匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与”\n”或”\r”之后的位置匹配。
$
匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与”\n”或”\r”之前的位置匹配。
*
零次或多次匹配前面的字符或子表达式。例如,zo* 匹配”z”和”zoo”。* 等效于 {0,}。
+
一次或多次匹配前面的字符或子表达式。例如,”zo+”与”zo”和”zoo”匹配,但与”z”不匹配。+ 等效于 {1,}。
?
零次或一次匹配前面的字符或子表达式。例如,”do(es)?”匹配”do”或”does”中的”do”。? 等效于 {0,1}。
{n}
n 是非负整数。正好匹配 n 次。例如,”o{2}”与”Bob”中的”o”不匹配,但与”food”中的两个”o”匹配。
{n,}
n 是非负整数。至少匹配 n 次。例如,”o{2,}”不匹配”Bob”中的”o”,而匹配”foooood”中的所有 o。”o{1,}”等效于”o+”。”o{0,}”等效于”o*”。
{n,m}
M 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。例如,”o{1,3}”匹配”fooooood”中的头三个 o。’o{0,1}’ 等效于 ‘o?’。注意:您不能将空格插入逗号和数字之间。
?
当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是”非贪心的”。”非贪心的”模式匹配搜索到的、尽可能短的字符串,而默认的”贪心的”模式匹配搜索到的、尽可能长的字符串。例如,在字符串”oooo”中,”o+?”只匹配单个”o”,而”o+”匹配所有”o”。
.
匹配除”\r\n”之外的任何单个字符。若要匹配包括”\r\n”在内的任意字符,请使用诸如”[\s\S]”之类的模式。
x|y
匹配 x 或 y。例如,’z
[xyz]
字符集。匹配包含的任一字符。例如,”[abc]”匹配”plain”中的”a”。
[^xyz]
反向字符集。匹配未包含的任何字符。例如,”[^abc]”匹配”plain”中”p”,”l”, “i”,”n”。
[a-z]
字符范围。匹配指定范围内的任何字符。例如,”[a-z]”匹配”a”到”z”范围内的任意小写字母。
[^a-z]
反向范围字符。匹配不在指定的范围内的任何字符。例如,”[^a-z]”匹配任何不在”a”到”z”范围内的任何字符。
\b
匹配一个字边界,即字与空格间的位置。例如,”er\b”匹配”never”中的”er”,不匹配”verb”中的”er”。
\B
非字边界匹配。”er\B”匹配”verb”中的”er”,但不匹配”never”中的”er”。
\cx
匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回车符。x 的值必须在A-Z 或 a-z 之间。如果不是这样,则假定 c 就是”c”字符本身。
\d
数字字符匹配。等效于 [0-9]。
\D
非数字字符匹配。等效于 [^0-9]。
\f
换页符匹配。等效于 \x0c 和 \cL。
\n
换行符匹配。等效于 \x0a 和 \cJ。
\r
匹配一个回车符。等效于 \x0d 和 \cM。
\s
匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。
\S
匹配任何非空白字符。与 [^ \f\n\r\t\v] 等效。
\t
制表符匹配。与 \x09 和 \cI 等效。
\v
垂直制表符匹配。与 \x0b 和 \cK 等效。
\w
匹配任何字类字符,包括下划线。与”[A-Za-z0-9_]”等效。
\W
与任何非单词字符匹配。与”[^A-Za-z0-9_]”等效。
面向对象 Groovy中的面向对象与Java很类似。
特征 特征是语言的结构构造,允许:
行为的组成。
接口的运行时实现。
与静态类型检查/编译的兼容性
它们可以被看作是承载默认实现和状态的接口,使用trait关键字定义trait。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Test { static void main(String[] args) { Student s = new Student() s.id = 20 s.age = 10 println(s.id) println(s.age) s.total() s.test1() s.test2() s.test3() } } interface Total { void total() } trait Marks implements Total { void test1() { println('Marks' ) } void total() { println('total' ) } } trait Marks1 extends Marks { int age; void test2() { println('Marks1 = ' + age) } } trait Marks2 { void test3() { println('Marks2' ) } } class Student implements Marks1 , Marks2 { int id }
闭包 概述 闭包是一个短的匿名代码块。它通常跨越几行代码。一个方法甚至可以将代码块作为参数。它们是匿名的。
1 2 3 4 5 static void main(String[] args) { def clos = {println "Hello World" }; clos.call(); clos(); }
在Groovy中,每个闭包都是groovy.lang.Closure的实例,执行闭包对象有两种,一是直接用括号+参数,二是调用call方法+参数。
闭包的形参 1 2 3 4 5 6 7 8 9 static void main(String[] args) { def clos = {param -> println "Hello ${param}" }; clos.call("World" ); } static void main(String[] args) { def clos = {println "Hello ${it}" }; clos.call("World" ); }
闭包和变量 闭包可以在定义闭包时引用变量。
1 2 3 4 5 6 7 8 9 10 11 12 static void main(String[] args) { def str1 = "Hello" ; def clos = {param -> println "${str1} ${param}" } clos.call("World" ); str1 = "Welcome" ; clos.call("World" ); } ->output: Hello World Welcome World
在方法中使用闭包 以下示例显示如何将闭包作为参数发送到方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Example { def static Display(clo) { clo.call("Inner" ); } static void main(String[] args) { def str1 = "Hello" ; def clos = { param -> println "${str1} ${param}" } clos.call("World" ); str1 = "Welcome" ; clos.call("World" ); Example.Display(clos); } } ->output: Hello World Welcome World Welcome Inner def filter(array, block) { for (val in array) { block(val) } } iarray = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] total = [] filter(iarray, { if (it % 2 == 0 ) total << it }) println total total = [] filter(iarray, { if (it > 5 ) total << it }) println total
当闭包作为最后一个参数时,可以有其它写法
1 filter(iarray) { if (it % 2 == 0 ) total << it }
集合和字符串中的闭包 List,Map和String方法接受一个闭包作为参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Example { static void main(String[] args) { def lst = [11 , 12 , 13 , 14 ]; lst.each {println it} } } class Example { static void main(String[] args) { def mp = ["TopicName" : "Maps" , "TopicDescription" : "Methods in Maps" ] mp.each {println it} mp.each {println "${it.key} maps to: ${it.value}" } } } class Example { static void main(String[] args) { def lst = [1 ,2 ,3 ,4 ]; lst.each {println it} println("The list will only display those numbers which are divisible by 2" ) lst.each{num -> if (num % 2 == 0 ) println num} } }
方法
方法
用法
find()
find方法查找集合中与某个条件匹配的第一个值。
findAll()
它找到接收对象中与闭合条件匹配的所有值。
any() & every()
方法any迭代集合的每个元素,检查布尔谓词是否对至少一个元素有效。
collect()
该方法通过集合收集迭代,使用闭包作为变换器将每个元素转换为新值。
闭包委托 在闭包内部,有三个内置对象this,owner,delegate,我们可以直接this,owner,delegate调用,或者用get方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Hello { static void main(String[] args) { def p = new Person(name: "hearing" ) p.clo() } } class Person { String name def clo = { println(name) println(this ) println(owner) println(delegate) def clo1 = { println(name) println(this ) println(owner) println(delegate) } clo1.delegate = Person clo1() } } ->output: hearing Person@35 d176f7 Person@35 d176f7 Person@35 d176f7 hearing Person@35 d176f7 Person$_closure1@6 ebc05a6 class Person
设置delegate的意义就是将闭包和一个具体的对象关联起来,在闭包中可以访问被代理对象的属性和方法,如果闭包所在的类或闭包中和被代理的类中有相同名称的方法,那么有几种代理策略:
Closure.OWNER_FIRST是默认策略。优先在owner寻找,owner没有再delegate
Closure.DELEGATE_FIRST:优先在delegate寻找,delegate没有再owner
Closure.OWNER_ONLY:只在owner中寻找
Closure.DELEGATE_ONLY:只在delegate中寻找
Closure.TO_SELF:
用法实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 # Person.groovy class Person { String name int age void eat(String food) { println("你喂的${food}真难吃" ) } @Override String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}' } } # Main.groovy class Main { void eat(String food){ println "我根本不会吃,不要喂我${food}" } def cc = { name = "hanmeimei" age = 26 eat("油条" ) } static void main(String... args) { Main main = new Main() Person person = new Person(name: "lilei" , age: 14 ) println person.toString() main.cc.delegate = person main.cc.setResolveStrategy(Closure.OWNER_FIRST) main.cc.call() println person.toString() } }
DSL(领域定义语言) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Gradle { String type String version String result def type(type) { this .type = type } def version(version) { this .version = version } def result(str) { result = version + type println str + result } static def build(closure) { Gradle gradle = new Gradle() closure.delegate = gradle closure.call() } } Gradle.build { type 'compile' version '1.11 ' result 'build: ' } -> output
Groovy XML 概述 Groovy语言提供了对XML语言的丰富支持,其两个最基本的XML类是:
XML生成器:groovy.xml.MarkupBuilder
XML解析器:groovy.util.XmlParser
MarkupBuilder 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import groovy.xml.MarkupBuilder class Example { static void main(String[] args) { def mp = [1 : ['Enemy Behind' , 'War, Thriller' ,'DVD' ,'2003' , 'PG' , '10' ,'Talk about a US-Japan war' ], 2 : ['Transformers' ,'Anime, Science Fiction' ,'DVD' ,'1989' , 'R' , '8' ,'A scientific fiction' ], 3 : ['Trigun' ,'Anime, Action' ,'DVD' ,'1986' , 'PG' , '10' ,'Vash the Stam pede' ], 4 : ['Ishtar' ,'Comedy' ,'VHS' ,'1987' , 'PG' , '2' ,'Viewable boredom ' ]] def mB = new MarkupBuilder() def MOVIEDB = mB.collection('shelf' : 'New Arrivals' ) { mp.each { sd -> mB.movie('title' : sd.value[0 ]) { type(sd.value[1 ]) format(sd.value[2 ]) year(sd.value[3 ]) rating(sd.value[4 ]) stars(sd.value[4 ]) description(sd.value[5 ]) } } } } }
运行上面代码会生成如下XML内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <collection shelf ='New Arrivals' > <movie title ='Enemy Behind' > <type > War, Thriller</type > <format > DVD</format > <year > 2003</year > <rating > PG</rating > <stars > PG</stars > <description > 10</description > </movie > <movie title ='Transformers' > <type > Anime, Science Fiction</type > <format > DVD</format > <year > 1989</year > <rating > R</rating > <stars > R</stars > <description > 8</description > </movie > <movie title ='Trigun' > <type > Anime, Action</type > <format > DVD</format > <year > 1986</year > <rating > PG</rating > <stars > PG</stars > <description > 10</description > </movie > <movie title ='Ishtar' > <type > Comedy</type > <format > VHS</format > <year > 1987</year > <rating > PG</rating > <stars > PG</stars > <description > 2</description > </movie > </collection >
XmlParser 对于上面的XML,可以使用下述方法解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import groovy.xml.MarkupBuilder import groovy.util.*class Example { static void main(String[] args) { def parser = new XmlParser() def doc = parser.parse("Movies.xml" ); doc.movie.each{ bk-> print("Movie Name:" ) println "${bk['@title']}" print("Movie Type:" ) println "${bk.type[0].text()}" print("Movie Format:" ) println "${bk.format[0].text()}" print("Movie year:" ) println "${bk.year[0].text()}" print("Movie rating:" ) println "${bk.rating[0].text()}" print("Movie stars:" ) println "${bk.stars[0].text()}" print("Movie description:" ) println "${bk.description[0].text()}" println("*******************************" ) } } }
运行上面的程序可以得到以下结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Movie Name: Enemy Behind Movie Type: War, Thriller Movie Format: DVD Movie year: 2003 Movie rating: PG Movie stars: 10 Movie description: Talk about a US-Japan war ******************************* Movie Name: Transformers Movie Type: Anime, Science Fiction Movie Format: DVD Movie year: 1989 Movie rating: R Movie stars: 8 Movie description: A schientific fiction ******************************* Movie Name: Trigun Movie Type: Anime, Action Movie Format: DVD Movie year: 1986 Movie rating: PG Movie stars: 10 Movie description: Vash the Stam pede! ******************************* Movie Name: Ishtar Movie Type: Comedy Movie Format: VHS Movie year: 1987 Movie rating: PG Movie stars: 2 Movie description: Viewable boredom
Groovy JSON 概述 Groovy语言提供了两个类来处理JSON格式的数据:
JSON生成器:groovy.json.JsonOutput
JSON解析器:groovy.json.JsonSlurper
JsonOutput
用法:Static string JsonOutput.toJson(datatype obj)
。
参数:可以是数据类型的对象,数字,布尔,字符,字符串,日期,地图,闭包等。
返回类型:一个JSON字符串。
1 2 3 4 5 6 7 8 import groovy.json.JsonOutputclass Example { static void main(String[] args) { def output = JsonOutput.toJson([name: 'John' , ID: 1 ]) println(output); } }
以上程序的输出如下:
JsonOutput也可以用于普通的Groovy对象:
1 2 3 4 5 6 7 8 9 10 11 12 import groovy.json.JsonOutput class Example { static void main(String[] args) { def output = JsonOutput.toJson([ new Student(name: 'John' , ID: 1 ), new Student(name: 'Mark' , ID: 2 )]) println(output); } } class Student { String name int ID; }
以上程序的输出如下:
1 [{"name" :"John" ,"ID" :1 },{"name" :"Mark" ,"ID" :2 }]
JsonSlurper JsonSlurper是一个将JSON文本或阅读器内容解析为Groovy数据结构的类,如Map,列表和原始类型,如Integer,Double,Boolean和String等。
用法:def slurper = new JsonSlurper()
JsonSlurper类自带了一些用于解析器实现的变体,例如当读取从Web服务器的响应返回的JSON时使用解析器JsonParserLax变量是有益的,此parser允许在JSON文本中存在注释以及没有引号字符串等。要指定此类型的解析器需要在定义JsonSlurper的对象时使用JsonParserType.LAX解析器类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 http.request( GET, TEXT ) { headers.Accept = 'application/json' headers.'User-Agent' = USER_AGENT response.success = { res, rd -> def jsonText = rd.text def parser = new JsonSlurper().setType(JsonParserType.LAX) def jsonResp = parser.parseText(jsonText) } }
类似地,以下附加的解析器类型在Groovy中可用:
JsonParserCharArray解析器基本上采用一个JSON字符串并对底层字符数组进行操作。在值转换期间,它复制字符子数组(称为“斩波”的机制)并单独操作它们。
JsonFastParser是JsonParserCharArray的一个特殊变体,是最快的解析器。JsonFastParser也称为索引覆盖解析器,在解析给定的JSON字符串期间,它尽可能努力地避免创建新的字符数组或String实例。它只保留指向底层原始字符数组的指针。此外,它会尽可能晚地推迟对象创建。
JsonParserUsingCharacterSource是一个非常大的文件的特殊解析器。它使用一种称为“字符窗口化”的技术来解析具有恒定性能特征的大型JSON文件(大型意味着超过2MB大小的文件)。
文本解析:
1 2 3 4 5 6 7 8 9 10 11 import groovy.json.JsonSlurper class Example { static void main(String[] args) { def jsonSlurper = new JsonSlurper() def object = jsonSlurper.parseText('{ "name": "John", "ID" : "1"}' ) println(object.name); println(object.ID); } }
以上程序的输出如下:
解析整数列表:
我们可以使用每个的List方法,并传递一个闭包。
1 2 3 4 5 6 7 8 9 import groovy.json.JsonSlurperclass Example { static void main(String[] args) { def jsonSlurper = new JsonSlurper() Object lst = jsonSlurper.parseText('{ "List": [2, 3, 4, 5] }' ) lst.each { println it } } }
以上程序的输出如下:
1 List=[2 , 3 , 4 , 5 , 23 , 42 ]
解析基本数据类型列表:
JSON解析器还支持字符串,数字,对象,true,false和null的原始数据类型。JsonSlurper类将这些JSON类型转换为相应的Groovy类型。
1 2 3 4 5 6 7 8 9 10 11 12 import groovy.json.JsonSlurperclass Example { static void main(String[] args) { def jsonSlurper = new JsonSlurper() def obj = jsonSlurper.parseText ''' {"Integer": 12, "fraction": 12.55, "double": 12e13}''' println(obj.Integer); println(obj.fraction); println(obj.double ); } }
以上程序的输出如下: