Проводка данных JSON с помощью Groovy HTTPBuilder

Я нашел этот документ о том, как публиковать данные JSON с использованием HttpBuilder. Я новичок в этом, но это очень простой пример и легко следовать. Вот код, предполагая, что я импортировал все необходимые зависимости.

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)

Я что-то пропустил? Я очень признателен за любую помощь, которую вы можете сделать.

Ответ 1

Я просмотрел HttpBuilder.java:1131, и я предполагаю, что кодировщик типа содержимого, который он извлекает в этом методе, нуль.

В большинстве примеров 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}"
    }
}

Ответ 2

У меня была такая же проблема некоторое время назад, и я нашел блог, который отметил, что 'requestContentType' должен быть установлен до 'body'. С тех пор я добавил комментарий "Установить ConentType перед телом или риском нулевого указателя" в каждом из моих методов httpBuilder.

Здесь изменение, которое я бы предложил для вашего кода:

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}"
    }
}

Ура!

Ответ 3

Если вам нужно выполнить 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 -> }
}    

Ответ 4

Я нашел ответ в этом сообщении: POST с HTTPBuilder → NullPointerException?

Это не принятый ответ, но это сработало для меня. Вам может потребоваться задать тип содержимого, прежде чем указывать атрибут body. Мне кажется глупым, но вот оно. Вы также можете использовать синтаксис 'send contentType, [attrs]', но мне было труднее unit test. Надеюсь, что это поможет (в конце концов)!

Ответ 5

Я отказался от HTTPBuilder в своем приложении Grails (по крайней мере, для POST) и использовал метод sendHttps, предлагаемый здесь.

(Имейте в виду, что если вы используете прямую Groovy вне приложения Grails, методы де/кодирования 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
}