Wie erhalte ich mit Jersey den vollständigen REST-Anforderungstext?

Lesezeit: 4 Minuten

Benutzer-Avatar
Markus Leon

Wie kann man den vollständigen HTTP-REST-Anforderungstext für a POST Anfrage mit Jersey?

In unserem Fall sind die Daten XML. Die Größe variiert zwischen 1 KB und 1 MB.

Das Dokumente scheinen darauf hinzudeuten, dass Sie verwenden sollten MessageBodyReader aber ich kann keine Beispiele sehen.

Es stellt sich heraus, dass Sie gar nicht viel tun müssen.

Siehe unten – der Parameter x enthält den vollständigen HTTP-Body (in unserem Fall XML).

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

  • Das Hinzufügen eines @Consumes(MediaType.TEXT_PLAIN) war auch für mich erforderlich.

    – Adam A

    4. Juli 2011 um 1:52 Uhr

  • Oder würde ich raten, @Consumes irgendetwas im Allgemeinen?

    – Adam A

    4. Juli 2011 um 1:53 Uhr

  • Dies ist äußerst hilfreich zum Debuggen von Nachrichten in Jersey, wo aus welchen Gründen auch immer eine Netzwerkinspektion keine Option ist, aber Codeänderungen (in meinem Fall lokale Integrationstests).

    – Patrick

    7. Januar 2013 um 17:41 Uhr

  • Ich erhalte folgende Fehlermeldung: Der Typ „java.lang.String“ kann nicht als Element gemarshallt werden, da ihm eine XmlRootElement-Anmerkung fehlt. Die Antwort von @sdorra hat mir geholfen: Verwenden Sie einfach org.w3c.dom.Document als Typ, nicht java.lang.String.

    – koppor

    15. Dezember 2013 um 21:39 Uhr

Sie könnten die Annotation @Consumes verwenden, um den vollständigen Text zu erhalten:

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

Notiz: Vergessen Sie nicht den Header “Content-Type: application/xml” bei der Anfrage.

Benutzer-Avatar
Benutzer2723428

Versuchen Sie dies mit diesem einzelnen Code:

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

    }
}

Die URL für try rest services endet …. /serviceX/doSomething

Da Sie Daten in XML übertragen, könnten Sie auch direkt von/zu Pojos (un)marshalieren.

Es gibt ein Beispiel (und weitere Informationen) in der trikot bedienungsanleitungdie ich hier kopiere:

POJO mit JAXB-Anmerkungen:

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

}      

Das XML, das produziert/konsumiert wird:

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

Benutzer-Avatar
toluju

Es scheint, dass Sie a verwenden müssten MessageBodyReader hier. Hier ist ein Beispiel mit 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
    }
  } 
}

Fügen Sie diese Klasse der Liste der Ressourcen hinzu, die Ihre Jersey-Bereitstellung verarbeiten wird (normalerweise über web.xml konfiguriert, denke ich). Sie können diesen Reader dann in einer Ihrer regulären Ressourcenklassen wie folgt verwenden:

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

Ich habe nicht überprüft, ob dies genau wie eingegeben funktioniert, aber das ist das Wesentliche. Mehr Lesestoff hier:

1136720cookie-checkWie erhalte ich mit Jersey den vollständigen REST-Anforderungstext?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy