2011-07-26 31 views
10

HttpBuilderを使用してJSONデータを投稿する方法については、this docが見つかりました。私はこれに新しいですが、それは非常に簡単な例であり、従うのは簡単です。必要なすべての依存関係をインポートしたと仮定して、コードを示します。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

私は(少なくとも、POSTのための)私のGrailsアプリケーションにHTTPBuilderをあきらめたとhereを提供sendHttps方法を使用していました。 (あなたは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メソッドのそれぞれに「BodyまたはRisk NULLポインタの前にConentTypeを設定する」というコメントを追加しました。

ここで私はあなたのコードを示唆している変更があります:

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としてオブジェクトをポストしようとするとnull文字列フィールドに空文字を入れますが、実際にNULLが必要です – dmitryvim

+0

こんにちはdmitryvim、 POSTリクエストのレスポンスJSONについてお話ししていますか?または、JSONの文字列フィールドをnullに設定しようとしていますか? – Robert

2

あなたはcontentTypeのJSONと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 -> } 
}  
関連する問題