66

POSTJersey を使用してリクエストの完全な HTTP REST リクエストボディを取得するにはどうすればよいですか?

この場合、データは XML になります。サイズは 1K から 1MB までさまざまです。

ドキュメントは、使用する必要があることを示しているようですがMessageBodyReader、例が表示されません。

4

5 に答える 5

93

多くのことをする必要はまったくないことがわかりました。

以下を参照してください - パラメータxには完全な HTTP 本文 (この場合は XML) が含まれます。

@POST
public Response go(String x) throws IOException {
    ...
}
于 2009-11-20T21:21:27.267 に答える
20

@Consumes アノテーションを使用して、本文全体を取得できます。

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

注意: リクエストによる「Content-Type: application/xml」ヘッダーを忘れないでください。

于 2011-02-28T12:34:00.020 に答える
16

この単一のコードを使用してこれを試してください:

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

    }
}

try rest services の URL は .... /serviceX/doSomething で終わります。

于 2013-08-30T15:42:23.113 に答える
9

xml でデータを転送しているため、pojo との間で直接 (un) マーシャリングすることもできます。

ジャージ ユーザー ガイドに例 (および詳細情報) があり、ここにコピーします。

JAXB アノテーション付きの POJO:

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

リソース:

@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:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<planet>
    <id>1</id>
    <name>Earth</name>
    <radius>1.0</radius>
</planet>
于 2012-06-14T22:34:48.883 に答える
0

ここでa を使用する必要があるようですMessageBodyReader。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
    }
  } 
}

このクラスを jersey デプロイメントが処理するリソースのリストに追加します (通常は web.xml で構成されていると思います)。次に、このリーダーを通常のリソース クラスの 1 つで次のように使用できます。

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

これが入力したとおりに機能することを確認していませんが、それが要点です。ここでもっと読む:

于 2009-11-20T00:03:58.110 に答える