关键字 关键字 关键字 关键字
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 声明的使用

示例如下:

  1. // 声明的使用
  2. String x ="x"
  3. def y = "y"
  4. var z ="z"
  5. //多次分配
  6. def (a, b, c) = [10, 20, 'foo']
  7. def (_, month, year) = "18th June 2009".split()
  8. def str = "In $month of $year" ;
  9. //分解对象中的属性
  10. def coordinates = new Coordinates(latitude: 43.23, longitude: 3.67)
  11. def (la, lo) = coordinates
  12. json{
  13. baseStatements x,y,z
  14. multiple a,b,c
  15. dataStr str
  16. destructuring la,lo
  17. }
  18. class Coordinates {
  19. double latitude
  20. double longitude
  21. double getAt(int idx) {
  22. if (idx == 0) latitude
  23. else if (idx == 1) longitude
  24. else throw new Exception("Wrong coordinate index, use 0 or 1")
  25. }
  26. }

运行结果:

{"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 &quot;blackdrag&quot; Theodorou
  </foo:to>
  How are you today?
</document>