web-dev-qa-db-ja.com

GroovyのHTTPBuilderを使用したJSONデータの投稿

HttpBuilderを使用してJSONデータを投稿する方法について this doc を見つけました。私はこれが初めてですが、非常に簡単な例であり、簡単に理解できます。必要な依存関係をすべてインポートしたと仮定した場合のコードは次のとおりです。

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)

私は何か見落としてますか?あなたができるどんな助けでも大いに感謝します。

13

HttpBuilder.Java:1131 を調べたところ、そのメソッドで取得するコンテンツタイプエンコーダーがnullであると推測しています。

ほとんどの POSTの例 ビルダーで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}"
    }
}
18
Rob Hruska

私は少し前に同じ問題を抱えていて、「body」の前に「requestContentType」を設定する必要があることを指摘するブログを見つけました。それ以来、httpBuilderの各メソッドに「本文またはリスク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}"
    }
}

乾杯!

8
Robert

POST contentType JSONを使用して複雑な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 -> }
}    

私はこの投稿で回答を見つけました: POST with HTTPBuilder-> NullPointerException?

それは受け入れられた答えではありませんが、私にとってはうまくいきました。 'body'属性を指定する前に、コンテンツタイプを設定する必要がある場合があります。私にはばかげているように見えますが、それはあります。また、 'send contentType、[attrs]'構文を使用することもできますが、単体テストの方が難しいことがわかりました。これが役立つことを願っています(現状のまま)。

1

GrailsアプリケーションでHTTPBuilderをあきらめて(少なくともPOST)は)、提供されているsendHttpsメソッド here を使用しました。

(Grailsアプリの外部でストレートGroovyを使用している場合、JSONのデコード/エンコードの手法は以下のものとは異なることに注意してください)

sendHttps()の次の行でcontent-typeをapplication/jsonに置き換えるだけです

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
}
0
perlyking