web-dev-qa-db-fra.com

Comment faire pour obtenir un corps complet REST demander à l'aide de Jersey?

Comment obtenir le corps complet de la requête HTTP REST) pour une demande POST à l'aide de Jersey?

Dans notre cas, les données seront XML. La taille varie de 1 Ko à 1 Mo.

Les docs semblent indiquer que vous devriez utiliser MessageBodyReader mais je ne vois aucun exemple.

58
Marcus Leon

Il s'avère que vous n'avez pas à faire grand chose du tout.

Voir ci-dessous - le paramètre x contiendra le corps complet de HTTP (XML dans notre cas).

@POST
public Response go(String x) throws IOException {
    ...
}
82
Marcus Leon

Vous pouvez utiliser l'annotation @Consumes pour obtenir le corps complet:

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

Note: N'oubliez pas l'en-tête "Content-Type: application/xml" de la requête.

17
sdorra

Essayez ceci en utilisant ce code unique:

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 pour les services de repos d'essai se termine ..../serviceX/doQuelque chose

12
user2723428

Comme vous transférez des données au format XML, vous pouvez également (dé) marshaler directement depuis/vers des pojos.

Il y a un exemple (et plus d'informations) dans le guide de l'utilisateur du maillot , que je copie ici:

POJO avec annotations JAXB:

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

Ressource:

@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);
    }

}      

Le XML qui est produit/consommé:

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

Il semble que vous deviez utiliser un MessageBodyReader ici. Voici un exemple utilisant 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
    }
  } 
}

Ajoutez cette classe à la liste des ressources que votre déploiement de jersey traitera (généralement configuré via web.xml, je pense). Vous pouvez ensuite utiliser ce lecteur dans l’une de vos classes de ressources habituelles, comme ceci:

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

Je n'ai pas vérifié que cela fonctionne exactement comme dactylographié, mais c'est l'essentiel. Plus de lecture ici:

0
toluju