我们正在尝试使用Groovy读取流式JSON数据(使用JsonSlurper),但我们只能通过重复解析源URL来做到这一点。我们想要做的是使其成为一种推送机制,这样,只要有新内容,我们都将获得回调。那可能吗? (如果您有Java解决方案,那也可以)

package json

import groovy.json.JsonParserType
import groovy.json.JsonSlurper

class JsonParser {
    private static final String JSON_URL = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3Fs%3DHM-B.ST%26f%3Dsl1d1t1c1ohgv%26e%3D.csv'%20and%20columns%3D'symbol%2Cprice%2Cdate%2Ctime%2Cchange%2Ccol1%2Chigh%2Clow%2Ccol2'&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"

    static main(args) {
        def url = new URL(JSON_URL)
        def urlStream = null
        try {
            urlStream = url.openStream()
            def jsonSlurper = new JsonSlurper().setType(JsonParserType.INDEX_OVERLAY)
            def jsonObj = jsonSlurper.parse(url)
            10.times {
                println jsonObj.query.created.toString()
                //println jsonObj.toString()
                jsonObj = jsonSlurper.parse(url)
                sleep(1000)
            }
        } finally {
            if (urlStream != null) urlStream.close()
        }
    }

}

最佳答案

为了使用推送通知(又名observer pattern),需要做一些通知。由于URL不会通知,因此您必须继续进行轮询。

除了线程方面的考虑之外,这是在轮询中使用轮询的一种简单方法。

import groovy.json.JsonParserType
import groovy.json.JsonSlurper

final String JSON_URL = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes.csv%3Fs%3DHM-B.ST%26f%3Dsl1d1t1c1ohgv%26e%3D.csv'%20and%20columns%3D'symbol%2Cprice%2Cdate%2Ctime%2Cchange%2Ccol1%2Chigh%2Clow%2Ccol2'&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"

poll(JSON_URL.toURL(), 5, 1000) { json ->
    println json
}

def poll(URL url, int iterations, int interval, Closure callback) {
    def jsonSlurper = new JsonSlurper().setType(JsonParserType.INDEX_OVERLAY)
    def lastTimestamp = null

    iterations.times {
        def json = jsonSlurper.parse(url)
        def timestamp = json.query.results.row.time

        if(timestamp != lastTimestamp) callback(json)
        lastTimestamp = timestamp
        sleep(interval)
    }
}


回调是一个闭包。

奖励:仅在数据的时间戳更改时才调用回调。

08-26 07:35