如何使用Jersey获得完整的REST请求体?

如何使用Jersey获取POST请求的完整HTTP REST请求主体?

在我们的例子中,数据将是XML。 大小从1K到1MB不等。

该文档似乎表明您应该使用MessageBodyReader但我看不到任何示例。

事实certificate,你不需要做太多的事情。

见下面 – 参数x将包含完整的HTTP正文(在我们的例子中是XML)。

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

你可以使用@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”头。

试试这个使用这个单一的代码:

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

尝试rest服务的URL结束…. / serviceX / doSomething

既然你是用xml传输数据,你也可以直接从/到pojos进行编组。

有一个例子(和更多的信息)在jersey用户指南 ,我在这里复制:

带有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> 

看来你必须在这里使用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.xmlconfiguration,我认为)。 然后,您可以在您的常规资源类之一中使用此读取器:

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

我没有证实,这是完全一样的打字,但这是它的要义。 更多阅读: