2011-07-26 14 views
10

He encontrado this doc sobre cómo publicar datos JSON utilizando HttpBuilder. Soy nuevo en esto, pero es un ejemplo muy sencillo y fácil de seguir. Aquí está el código, suponiendo que importé todas las dependencias requeridas.Publicación de datos JSON con HTTPBuilder de Groovy

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

Ahora mi problema es que me estoy haciendo una excepción de

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

¿Me he perdido algo? Agradeceré mucho cualquier ayuda que pueda hacer.

Respuesta

15

Eché un vistazo a HttpBuilder.java:1131, y supongo que el codificador de tipo de contenido que recupera en ese método es nulo.

La mayor parte de POST examples here establece la propiedad requestContentType en el constructor, que es lo que parece que el código está usando para obtener ese codificador. Inténtelo de la siguiente manera:

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

Gracias por la respuesta, pero todavía no es bueno :( java.lang .NullPointerExceptionat groovyx.net.http.HTTPBuilder $ RequestConfigDelegate.setBody (HTTPBuilder.java:1147) ¿Ha probado ese ejemplo en su máquina? ¿Funciona? Y también, en el valor de uri.path, ¿necesita ser un camino existente? –

+0

Parece que ya has avanzado; el nuevo NPE es cuando está tratando de encontrar el controlador de respuesta apropiado. La solicitud probablemente falló, por lo que querrá un manejador de fallas. Actualizaré mi ejemplo. –

+0

* "en el valor de uri.path, necesita ser una ruta existente" * - Si el host no existe, obtendrá algún tipo de error de conexión. Si existe, pero el recurso al que está enviando no existe, obtendrá un HTTP 404 o algo así. –

0

me di por vencido en HTTPBuilder en mi aplicación Grails (por correo al menos) y se utiliza el método sendHttps ofreció here.

(Tenga en cuenta que si está utilizando fuera recta maravilloso de una aplicación Grails, las técnicas de de/codifica el JSON serán diferentes a los de abajo)

basta con sustituir el tipo de contenido con application/json en el siguientes líneas de sendHttps()

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

también serán responsables de cálculo de referencias a sus datos 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

Encontré una respuesta en esta publicación: POST with HTTPBuilder -> NullPointerException?

No es la respuesta aceptada, pero funcionó para mí. Es posible que deba establecer el tipo de contenido antes de especificar el atributo 'cuerpo'. Me parece tonto, pero ahí está. También podría usar la sintaxis 'send contentType, [attrs]', pero me pareció más difícil realizar pruebas unitarias. Espero que esto ayude (tarde como es)!

8

Tuve el mismo problema hace un tiempo y encontré un blog que señalaba que 'requestContentType' debería establecerse antes de 'body'. Desde entonces, agregué el comentario 'Establecer ConentType antes cuerpo o arriesgar puntero nulo' en cada uno de mis métodos httpBuilder.

Aquí está el cambio que sugeriría para su código:

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

Salud!

+0

el único problema, si trato de publicar objetos como json, pone cadena vacía en campos de cadena nulos, pero realmente necesito nulos – dmitryvim

+0

Hola dmitryvim, ¿Estás hablando de la respuesta JSON de la solicitud POST? ¿O está intentando establecer campos de cadena dentro del cuerpo JSON para anular? – Robert

2

Si necesita ejecutar una POST con contentType JSON y pasar un complejo de datos JSON, tratar de convertir su cuerpo de forma manual:

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