2009-11-12 4 views

risposta

71

scopre che non c'è bisogno di fare molto a tutti.

Vedere di seguito: il parametro x conterrà il corpo HTTP completo (che è XML nel nostro caso).

@POST 
public Response go(String x) throws IOException { 
    ... 
} 
+5

Aggiunta di una @Consumes (MediaType.TEXT_PLAIN) era anche richiesto per me. –

+0

Oppure direi qualcosa su, in generale? –

+0

Ciò è estremamente utile per il debug dei messaggi in Jersey dove, per qualsiasi motivo, l'ispezione di rete non è un'opzione, ma le modifiche al codice sono (test di integrazione locale, nel mio caso). – Patrick

0

Sembra che dovresti usare uno MessageBodyReader qui. Ecco un esempio, usando JDOM:

import org.jdom.Document; 
import javax.ws.rs.ext.MessageBodyReader; 
import javax.ws.rs.ext.Provider; 
import javax.ws.rs.ext.MediaType; 
import javax.ws.rs.ext.MultivaluedMap; 
import java.lang.reflect.Type; 
import java.lang.annotation.Annotation; 
import java.io.InputStream; 

@Provider // this annotation is necessary! 
@ConsumeMime("application/xml") // this is a hint to the system to only consume xml mime types 
public class XMLMessageBodyReader implements MessageBodyReader<Document> { 
    private SAXBuilder builder = new SAXBuilder(); 

    public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { 
    // check if we're requesting a jdom Document 
    return Document.class.isAssignableFrom(type); 
    } 

    public Document readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) { 
    try { 
     return builder.build(entityStream); 
    } 
    catch (Exception e) { 
     // handle error somehow 
    } 
    } 
} 

Aggiungi questa classe per l'elenco delle risorse distribuzione maglia elaborerà (di solito configurati via web.xml, credo). È quindi possibile utilizzare questo lettore in una delle classi di risorse regolari come questo:

@Path("/somepath") @POST 
public void handleXMLData(Document doc) { 
    // do something with the document 
} 

non ho verificato che questo funziona esattamente come digitato, ma questo è l'essenza di esso. Più leggere qui:

14

è possibile utilizzare il @Consumes di annotazione per ottenere il corpo pieno:

import javax.ws.rs.Consumes; 
import javax.ws.rs.POST; 
import javax.ws.rs.Path; 
import javax.ws.rs.core.MediaType; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerConfigurationException; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import org.w3c.dom.Document; 

@Path("doc") 
public class BodyResource 
{ 
    @POST 
    @Consumes(MediaType.APPLICATION_XML) 
    public void post(Document doc) throws TransformerConfigurationException, TransformerException 
    { 
    Transformer tf = TransformerFactory.newInstance().newTransformer(); 
    tf.transform(new DOMSource(doc), new StreamResult(System.out)); 
    } 
} 

Nota: Non dimenticare il "Content-Type: application/xml" colpo di testa dalla richiesta.

5

Dato che si stanno trasferendo dati in xml, è possibile anche (un) marshal direttamente da/a pojos.

C'è un esempio (e più informazioni) nella jersey user guide, che copio qui:

POJO con annotazioni JAXB:

@XmlRootElement 
public class Planet { 
    public int id; 
    public String name; 
    public double radius; 
} 

risorse:

@Path("planet") 
public class Resource { 

    @GET 
    @Produces(MediaType.APPLICATION_XML) 
    public Planet getPlanet() { 
     Planet p = new Planet(); 
     p.id = 1; 
     p.name = "Earth"; 
     p.radius = 1.0; 

     return p; 
    } 

    @POST 
    @Consumes(MediaType.APPLICATION_XML) 
    public void setPlanet(Planet p) { 
     System.out.println("setPlanet " + p.name); 
    } 

}  

L'xml che viene prodotto/consumato:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<planet> 
    <id>1</id> 
    <name>Earth</name> 
    <radius>1.0</radius> 
</planet> 
10

Prova questo utilizzando questo codice unico:

import javax.ws.rs.POST; 
import javax.ws.rs.Path; 

@Path("/serviceX") 
public class MyClassRESTService { 

    @POST 
    @Path("/doSomething") 
    public void someMethod(String x) { 

     System.out.println(x); 
       // String x contains the body, you can process 
       // it, parse it using JAXB and so on ... 

    } 
} 

L'URL per i servizi di prova di riposo finisce ..../ServiceX/doSomething