关键字 | 关键字 | 关键字 | 关键字 |
---|---|---|---|
as | assert | break | case |
catch | class | const | continue |
def | default | do | else |
enum | extends | false | finally |
for | goto | if | implements |
import | in | instanceof | interface |
new | null | package | return |
super | switch | this | throw |
throws | trait | true | try |
var | while |
语法
statements 声明的使用
示例如下:
// 声明的使用
String x ="x"
def y = "y"
var z ="z"
//多次分配
def (a, b, c) = [10, 20, 'foo']
def (_, month, year) = "18th June 2009".split()
def str = "In $month of $year" ;
//分解对象中的属性
def coordinates = new Coordinates(latitude: 43.23, longitude: 3.67)
def (la, lo) = coordinates
json{
baseStatements x,y,z
multiple a,b,c
dataStr str
destructuring la,lo
}
class Coordinates {
double latitude
double longitude
double getAt(int idx) {
if (idx == 0) latitude
else if (idx == 1) longitude
else throw new Exception("Wrong coordinate index, use 0 or 1")
}
}
运行结果:
{"baseStatements":["x","y","z"],"multiple":[10,20,"foo"],"dataStr":"In June of 2009","destructuring":[43.23,3.67]}
import使用
默认导入的包如下:
java.lang.;java.util.;java.io.;java.net.;groovy.lang.;groovy.util.;java.math.BigInteger;java.math.BigDecimal
示例如下:
//单类导入
import groovy.xml.MarkupBuilder
import groovy.xml.StreamingMarkupBuilder
//包下所有的类导入
import groovy.xml.*
//静态导入
import static java.lang.String.format
//别名导入
import java.util.Date
import java.sql.Date as SQLDate
Date utilDate = new Date(1000L)
SQLDate sqlDate = new SQLDate(1000L)
json{
test utilDate instanceof java.util.Date,sqlDate instanceof java.sql.Date
IStatic format('String') == 'String1'
}
运行结果:
{"test":[true,true],"IStatic":false}
methods定义方法
示例如下:
// 创建方式的示例
def someMethod() { 'method called' }
String anotherMethod() { 'another method called' }
def thirdMethod(param1) { "$param1 passed" }
static String fourthMethod(String param1) { "$param1 passed" }
def foo(Map args) { "${args.name}: ${args.age}" }
//foo(name: 'Marie', age: 1) == "Marie: 1" 相等
def foo(Map args, Integer number) { "${args.name}: ${args.age}, and the number is ${number}" }
//foo(name: 'Marie', age: 1, 23) == "Marie: 1, and the number is 23"
//foo(23, name: 'Marie', age: 1) == "Marie: 1, and the number is 23"
def foo(String par1, Integer par2 = 1) { [name: par1, age: par2] }
// foo('Marie').age == 1 相等
def method(Object o1, Object o2) { 'o/o' }
def method(Integer i, String s) { 'i/s' }
def method(String s, Integer i) { 's/i' }
List<List<Object>> pairs = [['foo', 1], [2, 'bar'], [3, 4]]
// pairs.collect { a, b -> method(a, b) } == ['s/i', 'i/s', 'o/o']
json{
baseMethod someMethod(), anotherMethod(),thirdMethod("xxxxx"),fourthMethod("sssss")
fooMethod foo(name: 'Marie', age: 1),foo(23, name: 'Marie', age: 1),foo(name: 'Marie', age: 1, 23) , foo('Marie').age == 1, pairs.collect { a, b -> method(a, b) }
}
运行结果:
{"baseMethod":["method called","another method called","xxxxx passed","sssss passed"],"fooMethod":["Marie: 1","Marie: 1, and the number is 23","Marie: 1, and the number is 23",true,["s/i","i/s","o/o"]]}
object 对象相关操作使用
示例如下:
//类的定义请看json 输入之后
def pList = [new Person(id:1,name:"xxxx",age:30),new Person(id:2,name:"ffff",age:30)];
def p = pList.find{it.id == 123};
//p == null 加了?号就不会报NullPointerException
def seP = p?.name
//p = [id=1,name=xxx] 加了@符号,调用是Person的属性,而不是get方法
def xxx = pList.find{it.id == 1}
def xxxName = xxx.@name;
//返回list对象中Person对象的name属性值
def p_names = pList*.name;
//Method pointer operator
def str = 'example of method reference chenc'
def fun = str.&toUpperCase;
String describe(Person p) {
"$p.name is $p.age"
}
def action = this.&describe
def doSomething(String str) { str.toUpperCase() }
def doSomething(Integer x) { 2*x }
def reference = this.&doSomething
def foo = BigInteger.&new
def fortyTwo = foo('42')
def instanceMethod = String.&toUpperCase
int function(int x, int y, int z) {
x*y+z
}
def args = [4,5,6]
//Coercion operator
Integer x = 123
String s = x as String
//Call operator
class MyCallable {
int call(int x) {
2*x
}
}
def mc = new MyCallable()
// mc.call(2) == 4 相等
// mc(2) == 4 相等
//Operator overloading
class Bucket {
int size
Bucket(int size) { this.size = size }
Bucket plus(Bucket other) {
return new Bucket(this.size + other.size)
}
}
def b1 = new Bucket(4)
def b2 = new Bucket(11)
// (b1 + b2).size == 15 自动调用plus方法
json{
pData seP,xxxName,p_names
MethodOperator fun(),action(xxx),reference('foo'),reference(123),fortyTwo,instanceMethod('foo'),function(*args), (b1 + b2).size
}
//类的定义
class Person{
def id;
String name;
def age;
}
运行结果:
{"pData":[null,"xxxx",["xxxx","ffff"]],"MethodOperator":["EXAMPLE OF METHOD REFERENCE CHENC","xxxx is 30","FOO",246,42,"FOO",26,15]}
closures闭包使用
示例如下:
// 闭包
def code = { 123 }
//调用方式如下:code() == 123 或者 code.call() == 123
def isOdd = { int i -> i%2 != 0 }
//带参数闭包
def closureWithOneArg = { str -> str.toUpperCase() }
//默认参数用it
def greeting = { it -> "Hello, $it!" }
def multiConcat = { int n, String... args ->
args.join('-')*n
}
//类的方法中使用闭包
class Person {
String name
int age
String toString() { "$name is $age years old" }
String dump() {
def cl = {
String msg = this.toString()
println msg
msg
}
cl()
}
}
def p = new Person(name:'Janice', age:74)
def cl = { name.toUpperCase() }
cl.delegate = p
def plus2 = { it + 2 }
def times3 = { it * 3 }
def times3plus2 = plus2 << times3
// times3plus2(3) == 11
// times3plus2(4) == plus2(times3(4))
def plus2times3 = times3 << plus2
//times3plus2(3) == (times3 >> plus2)(3)
//plus2times3(5) == times3(plus2(5))
def factorial
factorial = { int n, def accu = 1G ->
if (n < 2) return accu
factorial.trampoline(n - 1, n * accu)
}
factorial = factorial.trampoline()
// factorial(1) == 1
// factorial(3) == 1 * 2 * 3
json{
baseClosure isOdd(3) == true,isOdd.call(2) == false
parametersClosure closureWithOneArg('groovy'),greeting('groovy'),multiConcat(2, 'abc','def')
classClosure p.dump(),cl()
operatorsClosure times3plus2(3),times3plus2(4),plus2times3(5) == times3(plus2(5)),times3plus2(3) == (times3 >> plus2)(3)
trampolineClosure factorial(1),factorial(3)
}
运行结果:
{"baseClosure":[true,true],"parametersClosure":["GROOVY","Hello, groovy!","abc-defabc-def"],"classClosure":["Janice is 74 years old","JANICE"],"operatorsClosure":[11,14,true,true],"trampolineClosure":[1,6]}
try catch 异常处理
示例如下:
// 异常处理示例
def exMessage= "";
try {
'moo'.toLong() // this will generate an exception
} catch ( e ) {
exMessage = e.message
}
def z
try {
def i = 7, j = 0
try {
def k = i / j
} finally {
z = 'reached here' //always executed even if Exception thrown
}
} catch ( e ) {
}
json{
baseEx exMessage,z
}
运行结果:
{"baseEx":["For input string: \"moo\"","reached here"]}
java 与java互调
示例如下:
import java.util.Date
import java.text.SimpleDateFormat
import java.util.*
def now = new Date(); // 创建对象
def df = new SimpleDateFormat('yyyy-MM-dd');
//创建java对象
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
//测试输出
json{
listData list
dateFormat df.format(now); // 调用方法
}
运行结果:
{"listData":[1,2,3],"dateFormat":"2022-07-12"}
if 判断使用
示例如下:
import groovy.transform.ToString
//if判断
def string;
def result;
if (string!=null && string.length()>0) {
result = 'Found'
} else {
result = 'Not found'
}
def result2 = (string!=null && string.length()>0) ? 'Found' : 'Not found'
def result3 = string ? 'Found' : 'Not found'
//Elvis assignment operator
@ToString
class Element {
String name
int atomicNumber
}
def he = new Element(name: 'Helium')
he.with {
name = name ?: 'Hydrogen' // existing Elvis operator
atomicNumber ?= 2 // new Elvis assignment shorthand
}
json{
ifTest result,result2,result3
withTest he
}
运行结果:
{"ifTest":["Not found","Not found","Not found"],"withTest":{"atomicNumber":2,"name":"Helium"}}
switch 判断使用
示例如下:
// switch 判断
def x = 1.23
def result = ""
switch ( x ) {
case "foo":
result = "found foo"
// lets fall through
case "bar":
result += "bar"
case [4, 5, 6, 'inList']:
result = "list"
break
case 12..30:
result = "range"
break
case Integer:
result = "integer"
break
case Number:
result = "number"
break
case ~/fo*/: // toString() representation of x matches the pattern?
result = "foo regex"
break
case { it < 0 }: // or { x < 0 }
result = "negative"
break
default:
result = "default"
}
json{
switchTest result
}
运行结果:
{"switchTest":"number"}
for 循环使用
示例如下:
// for循环示例
String message = ''
for (int i = 0; i < 5; i++) {
message += 'Hi '
}
def facts = []
def count = 5
for (int fact = 1, i = 1; i <= count; i++, fact *= i) {
facts << fact
}
def baNums = []
for (def (String u, int v) = ['bar', 42]; v < 45; u++, v++) {
baNums << "$u $v"
}
// iterate over a range
def x = 0
for ( i in 0..9 ) {
x += i
}
// iterate over a list
lx = 0
for ( i in [0, 1, 2, 3, 4] ) {
lx += i
}
// iterate over an array
def array = (0..4).toArray()
ax = 0
for ( i in array ) {
ax += i
}
// iterate over a map
def map = ['abc':1, 'def':2, 'xyz':3]
mx = 0
for ( e in map ) {
mx += e.value
}
mx2 = 0
for ( v in map.values() ) {
mx2 += v
}
// iterate over the characters in a string
def text = "abc"
def list = []
for (c in text) {
list.add(c)
}
json{
baseFor message,facts,baNums,x,lx,ax,mx,mx2,list
}
运行结果:
{"baseFor":["Hi Hi Hi Hi Hi ",[1,2,6,24,120],["bar 42","bas 43","bat 44"],45,10,10,6,6,["a","b","c"]]}
each遍历使用方式
示例如下:
// each遍历使用方式
def list =[1,2,3,4,5]
def str = "";
//默认使用it
list.each{
str +=it
}
def map = [name:"chenc",age:36,id:1]
def mapStr = "";
map.each{key,value ->
mapStr +="$key=$value,"
}
// `entry` is a map entry
map.each { entry ->
// "Name: $entry.key Age: $entry.value"
}
// `entry` is a map entry, `i` the index in the map
map.eachWithIndex { entry, i ->
// "$i - Name: $entry.key Age: $entry.value"
}
// Key, value and i as the index in the map
map.eachWithIndex { key, value, i ->
// "$i - Name: $key Age: $value"
}
json{
listStr str,mapStr
}
运行结果:
{"listStr":["12345","name=chenc,age=36,id=1,"]}
while 循环使用
示例如下:
// while循环示例
def x = 0
def y = 5
while ( y-- > 0 ) {
x++
}
// classic Java-style do..while loop
def count = 5
def fact = 1
do {
fact *= count++
} while(count > 1)
json{
baseWhile x,fact
}
运行结果:
string使用
示例如下:
import groovy.transform.ToString
def aMultilineString = '''line one
line two
line three'''
def name = 'Guillaume'
def greeting = "Hello ${name}"
def sum = "The sum of 2 and 3 equals ${2 + 3}"
def person = [name: 'Guillaume', age: 36]
def sParameterLessClosure = "1 + 2 == ${-> 3}"
def sOneParamClosure = "1 + 2 == ${ w -> w << 3}"
def date = "April, 1st"
def dollarSlashy = $/
Hello $name,
today we're ${date}.
$ dollar sign
$$ escaped dollar sign
\ backslash
/ forward slash
$/ escaped forward slash
$$$/ escaped opening dollar slashy
$/$$ escaped closing dollar slashy
/$
def text = 'nice cheese gromit!'
def x = text[2]
// x == 'c'
// x.class == String
def sub = text[5..10]
// sub == 'cheese'
@ToString
class Person {
String firstName
String lastName
}
def p = new Person(firstName: 'Jack', lastName: 'Nicholson')
//测试输出
json{
strTest greeting,aMultilineString,sum,"$person.name is $person.age years old",sParameterLessClosure,sOneParamClosure,dollarSlashy,x,sub
objStr p.toString()
}
运行结果
{"strTest":["Hello Guillaume","line one\nline two\nline three","The sum of 2 and 3 equals 5","Guillaume is 36 years old","1 + 2 == 3","1 + 2 == 3","\n Hello Guillaume,\n today we're April, 1st.\n\n $ dollar sign\n $ escaped dollar sign\n \\ backslash\n / forward slash\n / escaped forward slash\n $/ escaped opening dollar slashy\n /$ escaped closing dollar slashy\n","c","cheese"],"objStr":"Person(Jack, Nicholson)"}
collection 集合的使用
示例如下:
import java.util.Date
//Lists
def list = [1,2,3,4,5,6,7,8,9];
def heterogeneous = [1, "a", true] as LinkedList
heterogeneous << "C"
def str = "";
list.each{
str+="$it,"
}
//map应用
def map = [:];
map = ["tab":"user","user.id":"123","user.name":"chenc","user.age":"31"];
def tabMap = map.findAll{it.key.startsWith(map.tab);}
def mapData="";
tabMap.each {
def skey = it.key as String;
mapData = skey.tokenize('.');
}
//Range 范围
def range1 = 0..5
def sum = 0
range1.each { e -> sum += e }
def range2 = 0..<5
def sum2 = 0
range2.each { e -> sum2 += e }
def range3 = 'a'..'z'
//集合高级操作示例
//分组
def listgroup = ['a', 7, 'b', [2, 3]].groupBy {
it.class
}
//分组后的结果
//[(String) : ['a', 'b'],(Integer) : [7],(ArrayList): [[2, 3]]]
def listMapgroup = [
[name: 'Clark', city: 'London'], [name: 'Sharma', city: 'London'],
[name: 'Maradona', city: 'LA'], [name: 'Zhang', city: 'HK'],
[name: 'Ali', city: 'HK'], [name: 'Liu', city: 'HK'],
].groupBy { it.city }
//分组后的结果
//[ London: [[name: 'Clark', city: 'London'],[name: 'Sharma', city: 'London']],LA : [[name: 'Maradona', city: 'LA']],HK : [[name: 'Zhang', city: 'HK'],[name: 'Ali', city: 'HK'],[name: 'Liu', city: 'HK']],]
def people = [
1: [name:'Bob', age: 32, gender: 'M'],
2: [name:'Johnny', age: 36, gender: 'M'],
3: [name:'Claire', age: 21, gender: 'F'],
4: [name:'Amy', age: 54, gender:'F']
]
def bob = people.find { it.value.name == 'Bob' } // find a single entry
def females = people.findAll { it.value.gender == 'F' }
// both return entries, but you can use collect to retrieve the ages for example
def ageOfBob = bob.value.age
def agesOfFemales = females.collect {
it.value.age
}
// but you could also use a key/pair value as the parameters of the closures
def agesOfMales = people.findAll { id, person ->
person.gender == 'M'
}.collect { id, person ->
person.age
}
// `every` returns true if all entries match the predicate
def every = people.every { id, person ->
person.age > 18
}
// `any` returns true if any entry matches the predicate
def any = people.any { id, person ->
person.age == 54
}
json{
listTest list instanceof List,(8 in list),heterogeneous instanceof LinkedList,heterogeneous,str,listgroup,listMapgroup
mapTest mapData,map.tab,map["tab"]
rangeTest range1 instanceof Range,sum,sum2,range3
advanced bob,females,ageOfBob,agesOfFemales,agesOfMales,every,any
}
运行结果:
{"listTest":[true,true,true,[1,"a",true,"C"],"1,2,3,4,5,6,7,8,9,",{"class java.lang.String":["a","b"],"class java.lang.Integer":[7],"class java.util.ArrayList":[[2,3]]},{"London":[{"name":"Clark","city":"London"},{"name":"Sharma","city":"London"}],"LA":[{"name":"Maradona","city":"LA"}],"HK":[{"name":"Zhang","city":"HK"},{"name":"Ali","city":"HK"},{"name":"Liu","city":"HK"}]}],"mapTest":[["user","age"],"user","user"],"rangeTest":[true,15,10,["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]],"advanced":[{"value":{"name":"Bob","age":32,"gender":"M"},"key":1},{"3":{"name":"Claire","age":21,"gender":"F"},"4":{"name":"Amy","age":54,"gender":"F"}},32,[21,54],[32,36],true,true]}
高级语法
delegate 闭包内置对象
示例如下:
//闭包当前对象delegate,如果用this则DelegateMain无toUpperCase()方法
String.metaClass.shout = {
return delegate.toUpperCase()
}
println "Hello MetaProgramming".shout();
def md = new MyDelegate();
md << "1";
md << "2";
md << "3";
md << "4";
md << "55";
println "MyDelegate Date time ====>$md.time";
println "MyDelegate List size ====>${md.size()}";
class MyDelegate{
//@Delegate 是一个编译时注释,指导编译器将所有 delegate 的方法和接口推到外部类中。
@Delegate List list= new ArrayList();
@Delegate Date now = new Date();
}
运行结果:
HELLO METAPROGRAMMING
MyDelegate Date time ====>1657604416970
MyDelegate List size ====>5
操作类属性get和set
示例如下:
// 操作类属性get和set示例
class SomeGroovyClass {
def property1 = 'ha'
def field2 = 'ho'
def field4 = 'hu'
def getField1() {
return 'getHa'
}
def getProperty(String name) {
if (name != 'field3')
return metaClass.getProperty(this, name)
else
return 'field3'
}
}
def someGroovyClass = new SomeGroovyClass()
someGroovyClass.metaClass.setAttribute(someGroovyClass, 'field4', 'setAttribute ho')
// someGroovyClass.metaClass.getAttribute(someGroovyClass, 'field2') == 'ha'
// someGroovyClass.metaClass.getAttribute(someGroovyClass, 'field4') == 'ho'
class POGO {
String property
void setProperty(String name, Object value) {
this.@"$name" = 'overridden'
}
}
def pogo = new POGO()
pogo.property = 'a'
//propertyMissing 使用
class Foo {
def storage = [:]
def propertyMissing(String name, value) { storage[name] = value }
def propertyMissing(String name) { storage[name] }
//静态propertyMissing使用
static def $static_methodMissing(String name, Object args) {
return "Missing static method name is $name"
}
}
def f = new Foo()
f.foo = "bar"
class Person {
String name = "Fred"
}
//MetaProperty 使用
Person.metaClass.getProperty = { String name ->
def metaProperty = Person.metaClass.getMetaProperty(name)
def result
if(metaProperty) result = metaProperty.getProperty(delegate)
else {
result = "Flintstone"
}
result
}
def p = new Person()
json{
getPropertyTest someGroovyClass.field1,someGroovyClass.field2,someGroovyClass.field3,someGroovyClass.field4,someGroovyClass.metaClass.getAttribute(someGroovyClass, 'field4')
setPropertyTest pogo.property
propertyMissing f.foo, Foo.bar()
MetaProperty p.name,p.other
}
运行结果:
{"getPropertyTest":["getHa","ho","field3","setAttribute ho","setAttribute ho"],"setPropertyTest":"overridden","propertyMissing":["bar","Missing static method name is bar"],"MetaProperty":["Fred","Flintstone"]}
handy utilities 读取配置文件
示例如下:
// 读取配置文件的示例
def config = new ConfigSlurper().parse('''
app.date = new Date()
app.age = 42
app {
name = "Test${42}"
}
''')
def config2 = new ConfigSlurper('development').parse('''
environments {
development {
app.port = 8080
}
test {
app.port = 8082
}
production {
app.port = 80
}
}
''')
def slurper = new ConfigSlurper()
slurper.registerConditionalBlock('myProject', 'developers')
def config3 = slurper.parse('''
sendMail = true
myProject {
developers {
sendMail = false
}
}
''')
json{
configTest config.app.date,config.app.age,config.app.name,config2.app.port,config3.sendMail,"1111111"
}
运行结果:
{"configTest":["2022-07-12T05:42:45+0000",42,"Test42",8080,false,"1111111"]}
invokeMethod 默认方法调用
示例如下:
// 新接口
class SomeGroovyClass {
def invokeMethod(String name, Object args) {
return "called invokeMethod $name $args"
}
def test() {
return 'method exists'
}
}
def someGroovyClass = new SomeGroovyClass()
// someGroovyClass.test() == 'method exists'
// someGroovyClass.someMethod() == 'called invokeMethod someMethod []'
//====================GroovyObject Methods====================
class Stuff {
def invokeMe() { "foo" }
}
Stuff.metaClass.invokeMethod = { String name, args ->
def metaMethod = Stuff.metaClass.getMetaMethod(name, args)
def result
if(metaMethod) result = metaMethod.invoke(delegate,args)
else {
result = "bar"
}
result
}
def stf = new Stuff()
StringBuffer out = new StringBuffer("select * from USER");
def sqlB = new SqlBuilder(out);
sqlB.where{
or{
id "in",["1","2"];
login_name "Bob";
}
};
json{
invokeMethod someGroovyClass.test(),someGroovyClass.someMethod(),stf.invokeMe(),stf.doStuff()
sqlinvokeMethod sqlB.sql,sqlB.values
}
class SqlBuilder {
StringBuffer out;
int index = 0;
String condition = "and";
def values = [:];
boolean isDefCondition = true;
SqlBuilder( sql ){this.out = sql;}
def invokeMethod(String name, args){
def invokClosure = {
args[0].delegate = this;
args[0].call()
};
if(["and" , "or"].contains(name)){
condition = name;
invokClosure();
}else{
if(args[0] instanceof Closure){
out << " $name ";
invokClosure();
}else{
if(args[0]){
if(index != 0){
out << " $condition ";
}
isDefCondition = false;
if(args.size() > 1){
out << " $name ".toUpperCase();
out << args[0]+"(";
args[1].eachWithIndex {val,index->
if(index != 0){
out << ",";
}
out << "'$val'";
}
out << " )";
}else{
values[name]=args[0];
out << " ${name.toUpperCase()} = :$name "
}
index++;
}
}
}
}
def getSql(){
if(values.isEmpty() && isDefCondition){
out << " 1=1";
}
out;
}
}
运行结果:
{"invokeMethod":["method exists","called invokeMethod someMethod []","foo","bar"],"sqlinvokeMethod":["select * from USER where ID in('1','2' ) or LOGIN_NAME = :login_name ",{"login_name":"Bob"}]}
metaclasses 使用说明
示例如下:
// metaclasses 使用示例
class Foo { def bar() { "bar" } }
class MyFooMetaClass extends DelegatingMetaClass {
MyFooMetaClass(MetaClass metaClass) { super(metaClass) }
MyFooMetaClass(Class theClass) { super(theClass) }
Object invokeMethod(Object object, String methodName, Object[] args) {
def result = super.invokeMethod(object,methodName.toLowerCase(), args)
result.toUpperCase();
}
}
def mc = new MyFooMetaClass(Foo.metaClass)
mc.initialize()
Foo.metaClass =
Foo.metaClass = mc
def f = new Foo()
//=================Methods===========
class Book {
String title
}
Book.metaClass.titleInUpperCase << {-> title.toUpperCase() }
def b = new Book(title:"The Stand")
Book.metaClass.author = "Stephen King"
def b2 = new Book()
Book.metaClass.constructor << { String title -> new Book(title:title) }
def book = new Book('Groovy in Action - 2nd Edition')
//===========Borrowing Methods===============
class Person {
String name = "Fred"
}
class MortgageLender {
def borrowMoney() {
"buy house"
}
}
def lender = new MortgageLender()
Person.metaClass.buyHouse = lender.&borrowMoney
def p = new Person()
// "buy house" == p.buyHouse()
//==============Dynamic Method Names==================
def methodName = "Bob"
Person.metaClass."changeNameTo${methodName}" = {-> delegate.name = "Bob" }
def p2= new Person()
def p2Name = p2.name//Fred
p2.changeNameToBob()//Bob
// "Bob" == p2.name
//meta static invokeMethod
class Stuff {
static invokeMe() { "foo" }
}
Stuff.metaClass.'static'.invokeMethod = { String name, args ->
def metaMethod = Stuff.metaClass.getStaticMetaMethod(name, args)
def result
if(metaMethod) result = metaMethod.invoke(delegate,args)
else {
result = "bar"
}
result
}
List.metaClass.sizeDoubled = {-> delegate.size() * 2 }
def list = []
list << 1
list << 2
json{
MetaClass f.BAR() ,b.titleInUpperCase(),b2.author,book.title,p.buyHouse(),p2Name,p2.name
metaStaticMethod Stuff.invokeMe(),Stuff.doStuff(),list.sizeDoubled()
}
运行结果:
{"MetaClass":["BAR","THE STAND","Stephen King","Groovy in Action - 2nd Edition","buy house","Fred","Bob"],"metaStaticMethod":["foo","bar",4]}
thread 多线程的使用
示例如下:
// 新接口
Runnable run = {
println 'run in thread: ' + Thread.currentThread().getId()
println "========5555==========="
}
new Thread(run).start();
println "main thread:" + Thread.currentThread().getId();
println "========6==========="
运行结果:
run in thread: 1650
========5555===========
main thread:70
========6===========
transformations 注解的使用
示例如下:
// transformations 示例
import groovy.transform.*
class Named {
String name
}
@ToString(includeSuperProperties=true, ignoreNulls=true, includeNames=true, includeFields=true)
@TupleConstructor(force=true, defaults=false)
@TupleConstructor(force=true, defaults=false, includeFields=true)
@TupleConstructor(force=true, defaults=false, includeSuperProperties=true)
class Book extends Named {
Integer published
private Boolean fiction
Book() {}
}
// new Book("Regina", 2015).toString() == 'Book(published:2015, name:Regina)'
// new Book(2015, false).toString() == 'Book(published:2015, fiction:false)'
// new Book(2015).toString() == 'Book(published:2015)'
// new Book().toString() == 'Book()'
// Book.constructors.size() == 4
json{
transform new Book("Regina", 2015).toString(),new Book(2015, false).toString(),Book(2015).toString(),Book.constructors.size() ,Book().toString()
}
运行结果:
{"Book":2015,"Book":[],"transform":["Book(published:2015, name:Regina)","Book(published:2015, fiction:false)","null",4,"groovy.json.StreamingJsonBuilder$StreamingJsonDelegate@33b67e70"]}
IO操作
executing 执行外部命令
示例如下:
// 执行外部流程 示例
def process = "ls -l".execute()
json{
baseP "Found text ${process.text}"
}
运行结果:
{"baseP":"Found text total 672008\n-rw-r--r-- 1 root root 130014582 Jun 18 19:22 antengine-open-platform.jar\n-rw-r--r-- 1 root root 99326081 May 31 22:58 antengine-open-platform.jar.20220602\n-rw-r--r-- 1 root root 100969134 Jun 2 23:10 antengine-open-platform.jar.20220604\n-rw-r--r-- 1 root root 107816176 Jun 4 23:03 antengine-open-platform.jar.20220607\n-rw-r--r-- 1 root root 107817748 Jun 7 18:37 antengine-open-platform.jar.20220610\n-rw-r--r-- 1 root root 129688615 Jun 10 00:37 antengine-open-platform.jar.20220618\n-rw-r--r-- 1 root root 176 Jun 2 15:32 data2.bin\n-rw-r--r-- 1 root root 176 Jun 18 20:59 data2.src\n-rw-r--r-- 1 root root 23 Jun 2 15:32 data.bin\n-rw-r--r-- 1 root root 23 Jun 18 20:59 data.src\n-rw-r--r-- 1 root root 52 Jun 18 20:59 haiku.txt\n-rw-r--r-- 1 root root 30107 Jun 10 17:16 icons.xlsx\n-rw------- 1 root root 12432875 Jul 12 15:15 nohup.out\n"}
File 读写文件操作
示例如下:
// 文件读写
//写文件
new File('haiku.txt').withWriter('utf-8') { writer ->
writer.writeLine 'Into the ancient pond'
writer.writeLine 'A frog jumps'
writer.writeLine 'Water’s sound!'
}
//读文件
def text="";
new File( 'haiku.txt').eachLine { line, nb ->
text += "Line $nb: $line "
}
def list = new File('haiku.txt').collect {it}
def array = new File('haiku.txt') as String[]
byte[] contents = new File('haiku.txt').bytes
boolean b = true
String message = 'Hello from Groovy111'
def dataFile = new File('data.src');
// Serialize data into a file
dataFile.withDataOutputStream { out ->
out.writeBoolean(b)
out.writeUTF(message)
out.close();
}
def dataText = "";
new File('data.src').withDataInputStream { input ->
dataText = " ${input.readBoolean()} , ${input.readUTF()}"
}
class Person implements Serializable{
def id;
String name;
def age;
}
Person p = new Person(name:'Bob', age:76)
new File('data2.src').withObjectOutputStream { out ->
out.writeObject(p)
out.close()
}
def objFileText = new File('data2.src').getText('utf-8')
json{
fileText text
listText list,array
fileCont contents,dataText
object p,objFileText
}
运行结果:
{"fileText":"Line 1: Into the ancient pond Line 2: A frog jumps Line 3: Water\u2019s sound! ","listText":[["Into the ancient pond","A frog jumps","Water\u2019s sound!"],["Into the ancient pond","A frog jumps","Water\u2019s sound!"]],"fileCont":[[73,110,116,111,32,116,104,101,32,97,110,99,105,101,110,116,32,112,111,110,100,10,65,32,102,114,111,103,32,106,117,109,112,115,10,87,97,116,101,114,-30,-128,-103,115,32,115,111,117,110,100,33,10]," true , Hello from Groovy111"],"object":[{"id":null,"age":76,"name":"Bob"},"\ufffd\ufffd\u0000\u0005sr\u0000\u0006Person\ufffdV\ufffd\ufffd\u001bYY\ufffd\u0002\u0000\u0003L\u0000\u0003aget\u0000\u0012Ljava/lang/Object;L\u0000\u0002idq\u0000~\u0000\u0001L\u0000\u0004namet\u0000\u0012Ljava/lang/String;xpsr\u0000\u0011java.lang.Integer\u0012\u2824\ufffd\ufffd\ufffd8\u0002\u0000\u0001I\u0000\u0005valuexr\u0000\u0010java.lang.Number\ufffd\ufffd\ufffd\u001d\u000b\ufffd\ufffd\ufffd\u0002\u0000\u0000xp\u0000\u0000\u0000Lpt\u0000\u0003Bob"]}
FileTreeBuilder 文件树操作
示例如下:
// 新接口
tmpDir = File.createTempDir()
def fileTreeBuilder = new FileTreeBuilder(tmpDir)
fileTreeBuilder.dir('src') {
dir('main') {
dir('groovy') {
file('Foo.src', 'println "Hello"')
}
}
dir('test') {
dir('groovy') {
file('FooTest.src', 'class FooTest extends groovy.test.GroovyTestCase {}')
}
}
}
def file = new File(tmpDir, '/src/main/groovy/Foo.src')
println file.path
println file.text
println new File(tmpDir, '/src/test/groovy/FooTest.src').text
运行结果:
/tmp/groovy-generated-tmpdir-1221160231978156563/src/main/groovy/Foo.src
println "Hello"
class FooTest extends groovy.test.GroovyTestCase {}
SQL操作
本案例使用hsqldb,在操作数据时需要引入jdbc相关启动
connecting 数据连接
示例如下:
// 创建数据链接
import groovy.sql.Sql
import org.hsqldb.jdbc.JDBCDataSource
//创建数据链接
def url = 'jdbc:hsqldb:mem:yourDB'
def user = 'sa'
def password = ''
def driver = 'org.hsqldb.jdbcDriver'
def sql = Sql.newInstance(url, user, password, driver)
println sql
println "==============================="
// use 'sql' instance ...
sql.close()
//利用DataSource创建数据链接
def dataSource = new JDBCDataSource(
database: 'jdbc:hsqldb:mem:yourDB', user: 'sa', password: '')
def dssql = new Sql(dataSource)
println dssql
dssql.close();
运行结果:
groovy.sql.Sql@2836d8db
===============================
groovy.sql.Sql@58f177d8
executing sql执行器的使用
示例如下:
// 执行sql
import groovy.sql.Sql
import org.hsqldb.jdbc.JDBCDataSource
//利用DataSource创建数据链接
def dataSource = new JDBCDataSource(
database: 'jdbc:hsqldb:mem:yourDB', user: 'sa', password: '')
def sql = new Sql(dataSource)
try{
sql.execute '''DROP TABLE Author '''
}catch(e){
}
sql.execute '''
CREATE TABLE Author (
id INTEGER GENERATED BY DEFAULT AS IDENTITY,
firstname VARCHAR(64),
lastname VARCHAR(64)
);
'''
sql.close();
print "execute TABLE Author !!!!"
运行结果:
execute TABLE Author !!!!
sql基础增删改查操作
示例如下:
// 执行sql
import groovy.sql.Sql
import org.hsqldb.jdbc.JDBCDataSource
//利用DataSource创建数据链接
def dataSource = new JDBCDataSource(
database: 'jdbc:hsqldb:mem:yourDB', user: 'sa', password: '')
def sql = new Sql(dataSource)
//清空数据表
sql.execute " DELETE FROM Author "
sql.execute "INSERT INTO Author (firstname, lastname) VALUES ('Dierk', 'Koenig')"
def insertSql = 'INSERT INTO Author (firstname, lastname) VALUES (?,?)'
def params = ['Jon', 'Skeet']
def keys = sql.executeInsert insertSql, params
println keys
println "==============================="
def first = 'Guillaume'
def last = 'Laforge'
def myKeyNames = ['ID']
def myKeys = sql.executeInsert """
INSERT INTO Author (firstname, lastname)
VALUES (${first}, ${last})
""", myKeyNames
println myKeyNames
println "==============================="
def rowNum = 0
sql.query('SELECT firstname, lastname FROM Author') { resultSet ->
while (resultSet.next()) {
def first1 = resultSet.getString(1)
def last1 = resultSet.getString('lastname')
println "$first1 $last1"
}
}
println "==============================="
rowNum = 0
sql.eachRow('SELECT firstname, lastname FROM Author') { row ->
def first2 = row[0]
def last2 = row.lastname
println "$first2 $last2"
}
println "==============================="
rowNum = 0
sql.eachRow('SELECT firstname, lastname FROM Author') { row ->
def first3 = row[0]
def last3 = row.lastname
println "$first3 $last3"
}
println "==============================="
def first4 = sql.firstRow('SELECT lastname, firstname FROM Author')
println first4.values().sort().join(',')
println "==============================="
List authors = sql.rows('SELECT firstname, lastname FROM Author')
println authors.size()
println authors.collect { "$it.FIRSTNAME ${it[-1]}" }
println "==============================="
println sql.firstRow('SELECT COUNT(*) AS num FROM Author').num
println "==============================="
sql.execute "INSERT INTO Author (lastname) VALUES ('Thorvaldsson')"
sql.execute "UPDATE Author SET firstname='Erik' where lastname='Thorvaldsson'"
def updateSql = "UPDATE Author SET lastname='Pragt' where lastname='Thorvaldsson'"
def updateCount = sql.executeUpdate updateSql
println updateCount
println "==============================="
def row = sql.firstRow "SELECT * FROM Author where firstname = 'Erik'"
println "${row.firstname} ${row.lastname}"
println "==============================="
println sql.firstRow('SELECT COUNT(*) as num FROM Author').num
sql.execute "DELETE FROM Author WHERE lastname = 'Skeet'"
println sql.firstRow('SELECT COUNT(*) as num FROM Author').num
println 11111111111111111111111
sql.close();
运行结果:
[[1]]
===============================
[ID]
===============================
Dierk Koenig
Jon Skeet
Guillaume Laforge
===============================
Dierk Koenig
Jon Skeet
Guillaume Laforge
===============================
Dierk Koenig
Jon Skeet
Guillaume Laforge
===============================
Dierk,Koenig
===============================
3
[Dierk Koenig, Jon Skeet, Guillaume Laforge]
===============================
3
===============================
1
===============================
Erik Pragt
===============================
4
3
11111111111111111111111
sql高级使用
示例如下:
// 执行sql
import groovy.sql.Sql
import org.hsqldb.jdbc.JDBCDataSource
//利用DataSource创建数据链接
def dataSource = new JDBCDataSource(
database: 'jdbc:hsqldb:mem:yourDB', user: 'sa', password: '')
def sql = new Sql(dataSource)
//清空数据表
sql.execute " DELETE FROM Author "
sql.withTransaction {
sql.execute "INSERT INTO Author (firstname, lastname) VALUES ('Dierk', 'Koenig')"
sql.execute "INSERT INTO Author (firstname, lastname) VALUES ('Jon', 'Skeet')"
}
println sql.firstRow('SELECT COUNT(*) as num FROM Author').num
println "==============================="
def maxFirstnameLength
def metaClosure = { meta -> maxFirstnameLength = meta.getPrecision(1) }
def rowClosure = {}
def rowCountBefore = sql.firstRow('SELECT COUNT(*) as num FROM Author').num
try {
sql.withTransaction {
sql.execute "INSERT INTO Author (firstname) VALUES ('Dierk')"
sql.eachRow "SELECT firstname FROM Author WHERE firstname = 'Dierk'", metaClosure, rowClosure
sql.execute "INSERT INTO Author (firstname) VALUES (?)", 'X' * (maxFirstnameLength + 1)
}
} catch(ignore) { println ignore.message }
def rowCountAfter = sql.firstRow('SELECT COUNT(*) as num FROM Author').num
println rowCountBefore
println "==============================="
sql.execute " DELETE FROM Author "
sql.withBatch(3) { stmt ->
stmt.addBatch "INSERT INTO Author (firstname, lastname) VALUES ('Dierk', 'Koenig')"
stmt.addBatch "INSERT INTO Author (firstname, lastname) VALUES ('Paul', 'King')"
stmt.addBatch "INSERT INTO Author (firstname, lastname) VALUES ('Guillaume', 'Laforge')"
stmt.addBatch "INSERT INTO Author (firstname, lastname) VALUES ('Hamlet', 'D''Arcy')"
stmt.addBatch "INSERT INTO Author (firstname, lastname) VALUES ('Cedric', 'Champeau')"
stmt.addBatch "INSERT INTO Author (firstname, lastname) VALUES ('Erik', 'Pragt')"
stmt.addBatch "INSERT INTO Author (firstname, lastname) VALUES ('Jon', 'Skeet')"
}
println sql.firstRow('SELECT COUNT(*) as num FROM Author').num
println "==============================="
sql.execute " DELETE FROM Author "
def qry = 'INSERT INTO Author (firstname, lastname) VALUES (?,?)'
sql.withBatch(3, qry) { ps ->
ps.addBatch('Dierk', 'Koenig')
ps.addBatch('Paul', 'King')
ps.addBatch('Guillaume', 'Laforge')
ps.addBatch('Hamlet', "D'Arcy")
ps.addBatch('Cedric', 'Champeau')
ps.addBatch('Erik', 'Pragt')
ps.addBatch('Jon', 'Skeet')
}
println sql.firstRow('SELECT COUNT(*) as num FROM Author').num
println "==============================="
def qry1 = 'SELECT * FROM Author'
println sql.rows(qry1, 1, 3)*.firstname
println sql.rows(qry1, 4, 3)*.firstname
println sql.rows(qry1, 7, 3)*.firstname
println "==============================="
sql.execute "INSERT INTO Author (firstname, lastname) VALUES (:first, :last)", first: 'Dierk', last: 'Koenig'
sql.execute "INSERT INTO Author (firstname, lastname) VALUES (?.first, ?.last)", first: 'Jon', last: 'Skeet'
class Rockstar { String first, last }
def pogo = new Rockstar(first: 'Paul', last: 'McCartney')
def map = [lion: 'King']
sql.execute "INSERT INTO Author (firstname, lastname) VALUES (?1.first, ?2.lion)", pogo, map
json sql.rows(qry1)
println "==============================="
sql.close();
运行结果:
2
===============================
data exception: string data, right truncation; table: AUTHOR column: FIRSTNAME
2
===============================
7
===============================
7
===============================
[Dierk, Paul, Guillaume]
[Hamlet, Cedric, Erik]
[Jon]
===============================
[{"ID":15,"FIRSTNAME":"Dierk","LASTNAME":"Koenig"},{"ID":16,"FIRSTNAME":"Paul","LASTNAME":"King"},{"ID":17,"FIRSTNAME":"Guillaume","LASTNAME":"Laforge"},{"ID":18,"FIRSTNAME":"Hamlet","LASTNAME":"D'Arcy"},{"ID":19,"FIRSTNAME":"Cedric","LASTNAME":"Champeau"},{"ID":20,"FIRSTNAME":"Erik","LASTNAME":"Pragt"},{"ID":21,"FIRSTNAME":"Jon","LASTNAME":"Skeet"},{"ID":22,"FIRSTNAME":"Dierk","LASTNAME":"Koenig"},{"ID":23,"FIRSTNAME":"Jon","LASTNAME":"Skeet"},{"ID":24,"FIRSTNAME":"Paul","LASTNAME":"King"}]===============================
DataSets操作使用
示例如下:
import groovy.sql.Sql
import org.hsqldb.jdbc.JDBCDataSource
//利用DataSource创建数据链接
def dataSource = new JDBCDataSource(
database: 'jdbc:hsqldb:mem:yourDB', user: 'sa', password: '')
def sql = new Sql(dataSource)
def qry = """SELECT * FROM Author
WHERE (firstname > ?)
AND (lastname < ?)
ORDER BY lastname DESC"""
def params = ['Dierk', 'Pragt']
def result = sql.rows(qry, params)
println result*.firstname
println "==============================="
def authorDS = sql.dataSet('Author')
result = authorDS.findAll{ it.firstname > 'Dierk' }
.findAll{ it.lastname < 'Pragt' }
.sort{ it.lastname }
.reverse()
println result.rows()*.firstname
sql.close();
运行结果:
[Guillaume, Paul, Paul, Hamlet]
===============================
[Guillaume, Paul, Paul, Hamlet]
JSON操作
JsonBuilder 生成JSON
示例如下:
import groovy.json.*
def generator = new JsonGenerator.Options()
.excludeNulls()
.excludeFieldsByName('make', 'country', 'record')
.excludeFieldsByType(Number)
.addConverter(URL) { url -> "http://groovy-lang.org" }
.build()
JsonBuilder builder = new JsonBuilder(generator)
builder.records {
car {
name 'HSV Maloo'
make 'Holden'
year 2006
country 'Australia'
homepage new URL('http://example.org')
record {
type 'speed'
description 'production pickup truck with speed of 271kph'
}
}
}
println builder.toString()
运行结果:
{"records":{"car":{"name":"HSV Maloo","homepage":"http://groovy-lang.org"}}}
JsonOutput JSON输出
示例如下:
// JSON生成接口
import groovy.json.*
class Person {
String name
String title
int age
String password
Date dob
URL favoriteUrl
}
Person person = new Person(name: 'John', title: null, age: 21, password: 'secret',
dob: new Date(),
favoriteUrl: new URL('http://groovy-lang.org/'))
def generator = new JsonGenerator.Options()
.excludeNulls()
.dateFormat('yyyy@MM')
.excludeFieldsByName('age', 'password')
.excludeFieldsByType(URL)
.build()
json{
Test JsonOutput.toJson([name: 'John Doe', age: 42])
ObjectJson JsonOutput.toJson([ new Person(name: 'John'), new Person(name: 'Max') ])
generatorJson generator.toJson(person)
}
运行结果:
{"Test":"{\"name\":\"John Doe\",\"age\":42}","ObjectJson":"[{\"favoriteUrl\":null,\"password\":null,\"title\":null,\"age\":0,\"dob\":null,\"name\":\"John\"},{\"favoriteUrl\":null,\"password\":null,\"title\":null,\"age\":0,\"dob\":null,\"name\":\"Max\"}]","generatorJson":"{\"dob\":\"2022@07\",\"name\":\"John\"}"}
JsonSlurper JSON解析
示例如下:
// JSON解析接口
import groovy.json.*
def object = new JsonSlurper().parseText '''
{ "simple": 123,
"fraction": 123.66,
"exponential": "123e1211"
}'''
def jlist = new JsonSlurper().parseText('{ "myList": [4, 8, 15, 16, 23, 42] }')
json{
jSlurper object.exponential,jlist.myList
}
运行结果:
{"jSlurper":["123e1211",[4,8,15,16,23,42]]}
jsonXml JSON转xml
示例如下:
// 新接口
import com.antengine.util.JsonUtil
def xml = '''
<list>
<technology>
<name>Groovy</name>
<address>
<area>021</area>
<detail>中华人民共和国上海市</detail>
</address>
<address>
<area>010</area>
<detail>中华人民共和国北京市</detail>
</address>
</technology>
</list>
'''
def jsonStr = '''{
"root": {
"name": "binginsist",
"sex": "男",
"age": "25"
}
}'''
json {
// xmlSrc xml
xml2json JsonUtil.xml2Json(xml)
xml2jsonTechnology JsonUtil.xml2Json(xml, "list->technology")
xml2jsonTechnologyAddress JsonUtil.xml2Json(xml, "list->technology->address")
xml2jsonTechnologyAddress0 JsonUtil.xml2Json(xml, "list->technology->address[0]")
xml2jsonTechnologyAddress1 JsonUtil.xml2Json(xml, "list->technology->address[1]")
jsonSrc jsonStr
json2xml JsonUtil.json2Xml(jsonStr)
// 将集合放到 xml 里面,自定义一个 标签
json2xmlTarget JsonUtil.json2Xml( "[" + jsonStr + "," + jsonStr + "]", "persion")
}
运行结果:
{"xml2json":"{\"list\": {\"technology\": {\n \"address\": [\n {\n \"area\": \"021\",\n \"detail\": \"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd\u4e0a\u6d77\u5e02\"\n },\n {\n \"area\": \"010\",\n \"detail\": \"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd\u5317\u4eac\u5e02\"\n }\n ],\n \"name\": \"Groovy\"\n}}}","xml2jsonTechnology":"{\"address\":[{\"area\":\"021\",\"detail\":\"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd\u4e0a\u6d77\u5e02\"},{\"area\":\"010\",\"detail\":\"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd\u5317\u4eac\u5e02\"}],\"name\":\"Groovy\"}","xml2jsonTechnologyAddress":"[{\"area\":\"021\",\"detail\":\"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd\u4e0a\u6d77\u5e02\"},{\"area\":\"010\",\"detail\":\"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd\u5317\u4eac\u5e02\"}]","xml2jsonTechnologyAddress0":"{\"area\":\"021\",\"detail\":\"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd\u4e0a\u6d77\u5e02\"}","xml2jsonTechnologyAddress1":"{\"area\":\"010\",\"detail\":\"\u4e2d\u534e\u4eba\u6c11\u5171\u548c\u56fd\u5317\u4eac\u5e02\"}","jsonSrc":"{\n \"root\": {\n \"name\": \"binginsist\",\n \"sex\": \"\u7537\",\n \"age\": \"25\"\n }\n}","json2xml":"<root><sex>\u7537</sex><name>binginsist</name><age>25</age></root>","json2xmlTarget":"<persion><root><sex>\u7537</sex><name>binginsist</name><age>25</age></root></persion><persion><root><sex>\u7537</sex><name>binginsist</name><age>25</age></root></persion>"}
XML操作
DOMBuilder DOM方式解析xml
示例如下:
//
import groovy.xml.*
import groovy.xml.dom.DOMCategory
def CAR_RECORDS = '''
<records>
<car name='HSV Maloo' make='Holden' year='2006'>
<country>Australia</country>
<record type='speed'>Production Pickup Truck with speed of 271kph</record>
</car>
<car name='P50' make='Peel' year='1962'>
<country>Isle of Man</country>
<record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record>
</car>
<car name='Royale' make='Bugatti' year='1931'>
<country>France</country>
<record type='price'>Most Valuable Car at $15 million</record>
</car>
</records>
'''
def reader = new StringReader(CAR_RECORDS)
def doc = DOMBuilder.parse(reader)
def records = doc.documentElement
def dsize = 0;
use(DOMCategory) {
dsize = records.car.size()
}
json{
xmlDom dsize
}
运行结果:
{"xmlDom":3}
MarkupBuilder 生成xml
示例如下:
// 新接口
import groovy.xml.*
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.records() {
car(name: 'HSV Maloo', make: 'Holden', year: 2006) {
country('Australia')
record(type: 'speed', 'Production Pickup Truck with speed of 271kph')
}
car(name: 'Royale', make: 'Bugatti', year: 1931) {
country('France')
record(type: 'price', 'Most Valuable Car at $15 million')
}
}
//=============StreamingMarkupBuilder================
def xml2 = new StreamingMarkupBuilder().bind {
records {
car(name: 'HSV Maloo', make: 'Holden', year: 2006) {
country('Australia')
record(type: 'speed', 'Production Pickup Truck with speed of 271kph')
}
car(name: 'P50', make: 'Peel', year: 1962) {
country('Isle of Man')
record(type: 'size', 'Smallest Street-Legal Car at 99cm wide and 59 kg in weight')
}
car(name: 'Royale', make: 'Bugatti', year: 1931) {
country('France')
record(type: 'price', 'Most Valuable Car at $15 million')
}
}
}
json{
xmlTest writer.toString(),xml2.toString()
}
运行结果:
{"xmlTest":["<records>\n <car name='HSV Maloo' make='Holden' year='2006'>\n <country>Australia</country>\n <record type='speed'>Production Pickup Truck with speed of 271kph</record>\n </car>\n <car name='Royale' make='Bugatti' year='1931'>\n <country>France</country>\n <record type='price'>Most Valuable Car at $15 million</record>\n </car>\n</records>","<records><car name='HSV Maloo' make='Holden' year='2006'><country>Australia</country><record type='speed'>Production Pickup Truck with speed of 271kph</record></car><car name='P50' make='Peel' year='1962'><country>Isle of Man</country><record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record></car><car name='Royale' make='Bugatti' year='1931'><country>France</country><record type='price'>Most Valuable Car at $15 million</record></car></records>"]}
XmlParser 解析xml
示例如下:
//
import groovy.xml.*
def text = '''
<list>
<technology>
<name>Groovy</name>
</technology>
</list>
'''
def list = new XmlParser().parseText(text)
// list instanceof groovy.util.Node
// list.technology.name.text() == 'Groovy'
json{
xmlTest list.technology.name.text()
}
运行结果:
{"xmlTest":"Groovy"}
DOMBuilder JSON转xml
示例如下:
//
import groovy.xml.*
def text = '''
<list>
<technology>
<name>Groovy</name>
</technology>
</list>
'''
def list = new XmlSlurper().parseText(text)
// list instanceof groovy.xml.slurpersupport.GPathResult
// list.technology.name == 'Groovy'
json{
xmlTest list.technology.name
}
运行结果:
{"xmlTest":Groovy}
模板操作
TemplateEngine 模板引擎
示例如下:
// 模板引擎示例
//SimpleTemplateEngine模板示例
def text = 'Dear "$firstname $lastname",\nSo nice to meet you in <% print city %>.\nSee you in ${month},\n${signed}'
def binding = ["firstname":"Sam", "lastname":"Pullara", "city":"San Francisco", "month":"December", "signed":"Groovy-Dev"]
def engine = new groovy.text.SimpleTemplateEngine()
def template = engine.createTemplate(text).make(binding)
println template.toString()
println "==============================="
//StreamingTemplateEngine模板示例
text = '''\
Dear <% out.print firstname %> ${lastname},
We <% if (accepted) out.print 'are pleased' else out.print 'regret' %> \
to inform you that your paper entitled
'$title' was ${ accepted ? 'accepted' : 'rejected' }.
The conference committee.'''
template = new groovy.text.StreamingTemplateEngine().createTemplate(text)
binding = [
firstname : "Grace",
lastname : "Hopper",
accepted : true,
title : 'Groovy for COBOL programmers'
]
String response = template.make(binding)
println response
println "==============================="
//XmlTemplateEngine模板示例
binding = [firstname: 'Jochen', lastname: 'Theodorou', nickname: 'blackdrag', salutation: 'Dear']
engine = new groovy.text.XmlTemplateEngine()
text = '''\
<document xmlns:gsp='http://groovy.codehaus.org/2005/gsp' xmlns:foo='baz' type='letter'>
<gsp:scriptlet>def greeting = "${salutation}est"</gsp:scriptlet>
<gsp:expression>greeting</gsp:expression>
<foo:to>$firstname "$nickname" $lastname</foo:to>
How are you today?
</document>
'''
template = engine.createTemplate(text).make(binding)
println template.toString()
运行结果:
Dear "Sam Pullara",
So nice to meet you in San Francisco.
See you in December,
Groovy-Dev
===============================
Dear Grace Hopper,
We are pleased to inform you that your paper entitled
'Groovy for COBOL programmers' was accepted.
The conference committee.
===============================
<document type='letter'>
Dearest
<foo:to xmlns:foo='baz'>
Jochen "blackdrag" Theodorou
</foo:to>
How are you today?
</document>