2011-07-26 215 views
10

我發現this doc關於如何使用HttpBuilder發佈JSON數據。我對此很陌生,但這是一個非常直接的例子,很容易遵循。這是代碼,假設我已經導入了所有必需的依賴關係。現在使用Groovy的HTTPBuilder發佈JSON數據

def http = new HTTPBuilder('http://example.com/handler.php') 
http.request(POST, JSON) { req -> 
    body = [name:'bob', title:'construction worker'] 

    response.success = { resp, json -> 
     // response handling here 
    } 
} 

我的問題是,我得到的

java.lang.NullPointerException 
    at groovyx.net.http.HTTPBuilder$RequestConfigDelegate.setBody(HTTPBuilder.java:1131) 

異常我錯過了什麼?我將不勝感激您的任何幫助。

回答

15

我看了一下HttpBuilder.java:1131,我猜測它在該方法中檢索的內容類型編碼器爲null。

大部分POST examples here都在構建器中設置requestContentType屬性,這就是它看起來像代碼用來獲取該編碼器的屬性。嘗試設置這樣的:

import groovyx.net.http.ContentType 

http.request(POST) { 
    uri.path = 'http://example.com/handler.php' 
    body = [name: 'bob', title: 'construction worker'] 
    requestContentType = ContentType.JSON 

    response.success = { resp -> 
     println "Success! ${resp.status}" 
    } 

    response.failure = { resp -> 
     println "Request failed with status ${resp.status}" 
    } 
} 
+0

謝謝你的迴應,但仍然沒有很好:( 的java.lang .NullPointerExceptionat groovyx.net.http.HTTPBuilder $ RequestConfigDelegate.setBody(HTTPBuilder.java:1147) 你是否在你的機器上試過這個例子?它是否工作? 另外,關於uri.path的值,它是否需要成爲現有的路徑? –

+0

看起來你走得更遠;新的NPE是當它試圖找到適當的響應處理程序。請求可能失敗了,所以你需要一個失敗處理程序。我會更新我的例子。 –

+0

*「關於uri.path的值,它是否需要成爲現有路徑」* - 如果主機不存在,您將得到某種連接錯誤。如果它確實存在,但是您發佈的資源不存在,您將獲得HTTP 404或其他內容。 –

0

我在Grails應用程序(至少POST)放棄了HTTPBuilder和所使用的方法sendHttps提供here

(記住,如果你正在使用一個Grails應用的直Groovy的以外,對德的技術/編碼JSON會有所不同,以低於)

只是application/json在更換內容類型的sendHttps()

httpPost.setHeader("Content-Type", "text/xml") 
... 
reqEntity.setContentType("text/xml") 

以下行也將負責爲您的編組JSON數據

import grails.converters.* 

def uploadContact(Contact contact){ 
    def packet = [ 
     person : [ 
     first_name: contact.firstName, 
     last_name: contact.lastName, 
     email: contact.email, 
     company_name: contact.company 
     ] 
    ] as JSON //encode as JSON 
    def response = sendHttps(SOME_URL, packet.toString()) 
    def json = JSON.parse(response) //decode response 
    // do something with json 
} 
1

我在這篇文章中找到了答案:POST with HTTPBuilder -> NullPointerException?

這不是公認的答案,但它對我有用。您可能需要在指定「body」屬性之前設置內容類型。這對我來說似乎很愚蠢,但它就是這樣。你也可以使用'send contentType,[attrs]'語法,但是我發現單元測試更加困難。希望這有助於(遲到)!

8

我前段時間遇到同樣的問題,發現一個博客指出'requestContentType'應該放在'body'之前。從那以後,我在每個httpBuilder方法中都添加了註釋'Set ConentType before body or risk null pointer'。

這裏是我會建議爲你的代碼的變化:

import groovyx.net.http.ContentType 

http.request(POST) { 
    uri.path = 'http://example.com/handler.php' 
    // Note: Set ConentType before body or risk null pointer. 
    requestContentType = ContentType.JSON 
    body = [name: 'bob', title: 'construction worker'] 

    response.success = { resp -> 
     println "Success! ${resp.status}" 
    } 

    response.failure = { resp -> 
     println "Request failed with status ${resp.status}" 
    } 
} 

乾杯!

+0

唯一的問題,如果我嘗試將對象作爲JSON發佈,它將空字符串放在空字符串字段上,但我確實需要空值 – dmitryvim

+0

嗨dmitryvim, 你在說POST請求的響應JSON嗎?或者你是否試圖將正文JSON中的字符串字段設置爲null? – Robert

2

如果您需要執行與JSON的contentType一個POST,並通過一個複雜的JSON數據,嘗試你的身體手動轉換:

def attributes = [a:[b:[c:[]]], d:[]] //Complex structure 
def http = new HTTPBuilder("your-url") 
http.auth.basic('user', 'pass') // Optional 
http.request (POST, ContentType.JSON) { req -> 
    uri.path = path 
    body = (attributes as JSON).toString() 
    response.success = { resp, json -> } 
    response.failure = { resp, json -> } 
}