Comment obtenir le corps de la demande complète REST en utilisant Jersey?
Question
Comment peut-on obtenir le plein corps de la requête HTTP REST pour une demande de POST
en utilisant Jersey?
Dans notre cas, les données seront XML. Taille varierait de 1K à 1Mo.
Le docs semblent indiquer que vous devez utiliser MessageBodyReader
mais Je ne vois pas d'exemples.
La solution
Il s'avère que vous ne devez pas faire grand-chose.
Voir ci-dessous -. x
le paramètre contiendra le corps HTTP complète (qui est XML dans notre cas)
@POST
public Response go(String x) throws IOException {
...
}
Autres conseils
Vous pouvez utiliser l'annotation @Consumes pour obtenir le corps entier:
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));
}
}
Remarque : Ne pas oublier le "Content-Type: application / xml". En-tête par la demande
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 try se termine .... / ServiceX / doSomething
Puisque vous transférez des données en XML, vous pouvez aussi (un) maréchal directement à partir de / à POJO.
Il y a un exemple (et plus d'informations) dans le Guide , que je copie ici:
POJO avec annotations JAXB:
@XmlRootElement
public class Planet {
public int id;
public String name;
public double radius;
}
Ressources:
@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);
}
}
xml qui obtient produit / consommé:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<planet>
<id>1</id>
<name>Earth</name>
<radius>1.0</radius>
</planet>
Il ne semble que vous devez utiliser un MessageBodyReader
ici. Voici un exemple, en 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 de 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 ordinaires 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 typé, mais c'est l'essentiel. Plus de lire ici: