Gradle入門系列(二)——groovy高階語法

GitLqr發表於2019-01-05

groovy高階語法

一、json操作

使用groovy自帶的json工具進行json操作

groovy.json.JsonSlurper:將json原資料轉成實體物件groovy.json.JsonOutput:將實體物件轉成json資料

def list = [  new Person(name: 'John', age: 25),  new Person(name: 'Major', age: 26)]// 物件轉jsondef json = JsonOutput.toJson(list)println json                         // 一行輸出json字串println JsonOutput.prettyPrint(json) // 以json格式輸出json字串// json轉物件def jsonSlurper = new JsonSlurper()jsonSlurper.parse(obj) // jsonSlurper.parseText(str)複製程式碼

groovy是完全相容java的,所以java能使用的第三方json庫(如:gson、fastjson),在groovy中也同樣可以匯入使用,但一般不建議這麼做,groovy本身提供的工具箱就已經滿足日常開發需求了。

下面是groovy將網路json資料轉成實體物件,並訪問對應屬性欄位的例子:

def response = getNetworkData("http://xxx/data.json")println response.data.name        // 不需要定義具體的實體類,就可以直接訪問對應的屬性欄位def getNetworkData(String url){ 
// 傳送http請求 def connection = new URL(url).openConnection() connection.setRequestMethod('GET') connection.connect() // 該方法會阻塞執行緒 def response = connection.content.text // 將json轉化為實體物件 def jsonSluper = new JsonSlurper() return jsonSluper.parseText(response)
}複製程式碼

二、xml檔案操作

java xml處理:DOM文件驅動處理方式、SAX事件驅動處理方式。groovy則為我們提供了xml工具箱:

groovy.xml.XmlSlurper:將xml原資料轉成實體物件groovy.xml.MarkupBuilder:將實體物件轉成xml資料

1、解析xml

final String xml = '''  <
response version-api="2.0">
<
value>
<
books id="1" classification="android">
<
book available="20" id="1">
<
title>
瘋狂Android講義<
/title>
<
author id="1">
李剛<
/author>
<
/book>
<
book available="14" id="2">
<
title>
第一行程式碼<
/title>
<
author id="2">
郭林<
/author>
<
/book>
<
book available="13" id="3">
<
title>
Android開發藝術探索<
/title>
<
author id="3">
任玉剛<
/author>
<
/book>
<
book available="5" id="4">
<
title>
Android原始碼設計模式<
/title>
<
author id="4">
何紅輝<
/author>
<
/book>
<
/books>
<
books id="2" classification="web">
<
book available="10" id="1">
<
title>
Vue從入門到精通<
/title>
<
author id="4">
李剛<
/author>
<
/book>
<
/books>
<
/value>
<
/response>
'''
def xmlSlurper = new XmlSlurper() def response = xmlSlurper.parseText(xml) // 讀取並解析xml資料println response.value.books[0].book[0].title.text() // 獲取標籤內容println response.value.books[0].book[0].@available // 獲取標籤屬性// 獲取所有作者是"李剛"的書籍名稱// 方法一:平行遍歷xml資料def list = []response.value.books.each {
books ->
books.book.each {
book ->
def author = book.author.text() if(author.equals('李剛')){
list.add(book.title.text())
}
}
}println list.toListString()// 方法二:深度遍歷xml資料 // response.depthFirst().findAll 相當於 response.'**'.findAlldef titles = response.depthFirst().findAll {
book ->
return book.author.text() == '李剛' ? true : false
}// 獲取id為2的book節點的title內容// 廣度遍歷xml資料// response.value.books.children().findAll 相當於 response.value.books.'*'.findAlldef names = response.value.books.children().findAll {
node ->
node.name() == 'book' &
&
node.@id == '2'
}.collect {
node ->
return node.title.text()
}複製程式碼
李剛20[瘋狂Android講義, Vue從入門到精通]複製程式碼

其他:

  • 深度遍歷 depthFirst()可以使用’**’表示。
  • 廣度遍歷 children()可以使用’*’表示。

2、生成xml

/** * 生成xml格式資料 * <
langs type='current' count='3' mainstream='true'>
* <
language flavor='static' version='1.5'>
java<
/language>
* <
language flavor='dynamic' version='1.6.0'>
Groovy<
/language>
* <
language flavor='dynamic' version='1.9'>
JavaScript<
/language>
* <
/langs>
*/
def sw = new StringWriter()def xmlBuilder = new MarkupBuilder(sw) // 用來生成xml資料的核心類// 使用偽方法建立 根結點langs,在引數括號中指定標籤屬性key-valuexmlBuilder.langs(type: 'current', count: '3', mainstream: 'true'){
// 同樣,使用偽方法建立 language結點,不指定key時,該value將作為標籤內容 language(flavor: 'static', version: '1.5', 'Java') language(flavor: 'dynamic', version: '1.6.0', 'Groovy') language(flavor: 'dynamic', version: '1.9', 'JavaScript')
}println sw複製程式碼

上面是使用MarkupBuilder直接編寫輸出xml資料,但實際開發中,往往是將實體物件轉成xml,在明白MarkupBuilder的用法之後,這樣的需求處理也是差不多的:

def sw = new StringWriter()def xmlBuilder = new MarkupBuilder(sw)def langs = new Langs()xmlBuilder.langs(type: langs.type, count: langs.count, mainstream: langs.mainstream) { 
langs.languages.each {
lang->
language (flavor: lang.flavor, version: lang.version, lang.value)
}
}class Langs{ String type = 'current' String count = '3' String mainstream = 'true' def Languages = [ new Language(flavor: 'static', version: '1.5', value: 'java'), new Language(flavor: 'dynamic', version: '1.6.0', value: 'Groovy') new Language(flavor: 'dynamic', version: '1.9', value: 'JavaScript') ]
}class Language{ String flavor String version String value
}...複製程式碼

三、檔案操作

java檔案處理:節點流(InputStream、OutputSteam及其子類)、處理流(Reader、Writer及其子類)groovy檔案處理:所有java對檔案的處理類,groovy都可以使用;groovy擴充套件了許多更加快捷和強大的方法(ResourceGroovyMethods)。

def file = new File('../../GroovySpecification.iml')file.eachLine { 
line ->
// 遍歷檔案中的每一行 println line
}def text = file.getText() // 返回檔案中所有行內容的文字def result = file.readLines() // 返回一個一行行文字內容的Listdef readerBuffer = file.withReader {
reader ->
// 讀取檔案中前100個字元 char[] buffer = new char[100] reader.read(buffer) return buffer
}// copy檔案def copy(String srcPath, String destPath) {
try{
// 建立目標檔案 def destFile = new File(destPath) if(!destFile.exists()){
destFile.createNewFile()
} // 開始拷貝 new File(srcPath).withReader{
reader ->
def lines = reader.readLines() destFile.withWriter{
writer ->
lines.each{
line ->
writer.append(line+"\r\n")
}
}
}
}catch(Exception e){
e.printStackTrace()
}
}// 物件儲存到檔案def saveObject(Object object, String path){
try{
// 建立目標檔案 def destFile = new File(path) if(!destFile.exists()){
destFile.createNewFile()
} destFile.withObjectOutputStream {
out ->
out.writeObject(object)
}
}catch(Exception e){
e.printStackTrace()
}
}// 從檔案讀取物件def readObject(String path){
def obj = null try{
def file = new File(path) if(file == null || !file.exists()) return null // 從檔案中讀取物件 file.withObjectInputStream{
input ->
obj = input.readObject()
}
}catch(Exception e){
e.printStackTrace()
} return obj
}複製程式碼

四、與java對比及總結

  • 寫法上,沒有java那麼多限制(如:分號、return)
  • 功能上,對java已有的功能進行了極大的擴充套件
  • 作用上,即可以編寫應用,也可以編寫指令碼

來源:https://juejin.im/post/5c307751e51d4551c87fe1ca

相關文章