web-dev-qa-db-fra.com

Publication de données JSON avec HTTPBuilder de Groovy

J'ai trouvé ce document sur la manière de publier des données JSON à l'aide de HttpBuilder. Je suis novice dans ce domaine, mais c’est un exemple très simple et facile à suivre. Voici le code, en supposant que j'ai importé toutes les dépendances requises.

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

Maintenant, mon problème est, je reçois une exception de

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

Ai-je manqué quelque chose? J'apprécierai énormément toute aide que vous pourrez faire.

13

J'ai jeté un coup d'oeil à HttpBuilder.Java:1131 , et je suppose que l'encodeur de type de contenu qu'il récupère dans cette méthode est null.

La plupart des exemples POST ici définissent la propriété requestContentType dans le générateur, qui ressemble à ce que le code utilise pour obtenir cet encodeur. Essayez de le configurer comme ceci:

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

J'ai eu le même problème il y a quelque temps et j'ai trouvé un blog qui a noté que 'requestContentType' devrait être défini avant 'body'. Depuis lors, j'ai ajouté le commentaire "Définir ConentType avant le pointeur null body ou risk" dans chacune de mes méthodes httpBuilder.

Voici le changement que je suggérerais pour votre code:

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

À votre santé!

8
Robert

Si vous devez exécuter un POST avec contentType JSON et transmettre des données JSON complexes, essayez de convertir votre corps manuellement:

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

J'ai trouvé une réponse dans cet article: POST avec HTTPBuilder -> NullPointerException?

Ce n'est pas la réponse acceptée, mais cela a fonctionné pour moi. Vous devrez peut-être définir le type de contenu avant de spécifier l'attribut 'body'. Cela me semble stupide, mais voilà. Vous pouvez également utiliser la syntaxe 'send contentType, [attrs]', mais j'ai trouvé plus difficile d'effectuer des tests unitaires. J'espère que cela aide (tard comme c'est)!

1

J'ai abandonné HTTPBuilder dans mon application Grails (pour POST au moins) et utilisé la méthode sendHttps offerte here .

(N'oubliez pas que si vous utilisez Groovy directement en dehors d'une application Grails, les techniques de de/encodage du JSON seront différentes de celles décrites ci-dessous.)

Il suffit de remplacer le type de contenu par application/json dans les lignes suivantes de sendHttps()

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

Vous serez également responsable de la gestion de vos données 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