Java 如何使用 Jersey 获取完整的 REST 请求正文?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1725315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:54:58  来源:igfitidea点击:

How to get full REST request body using Jersey?

javarestjersey

提问by Marcus Leon

How can one get the full HTTP REST request body for a POSTrequest using Jersey?

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

In our case the data will be XML. Size would vary from 1K to 1MB.

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

The docsseem to indicate you should use MessageBodyReaderbut I can't see any examples.

文件似乎表明,你应该使用MessageBodyReader,但我看不到任何的例子。

采纳答案by Marcus Leon

Turns out you don't have to do much at all.

事实证明你根本不需要做太多事情。

See below - the parameter xwill contain the full HTTP body (which is XML in our case).

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

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

回答by toluju

It does seem you would have to use a MessageBodyReaderhere. Here's an example, using jdom:

看来您必须在MessageBodyReader此处使用 a 。这是一个使用 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
    }
  } 
}

Add this class to the list of resources your jersey deployment will process (usually configured via web.xml, I think). You can then use this reader in one of your regular resource classes like this:

将此类添加到您的 jersey 部署将处理的资源列表中(我认为通常通过 web.xml 进行配置)。然后,您可以在您的常规资源类之一中使用此阅读器,如下所示:

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

I haven't verified that this works exactly as typed, but that's the gist of it. More reading here:

我还没有验证这是否与输入的完全一样,但这就是它的要点。更多阅读在这里:

回答by sdorra

You could use the @Consumes annotation to get the full body:

您可以使用 @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));
  }
}

Note: Don't forget the "Content-Type: application/xml" header by the request.

注意:不要忘记请求中的“Content-Type: application/xml”标头。

回答by GlennV

Since you're transferring data in xml, you could also (un)marshal directly from/to pojos.

由于您在 xml 中传输数据,因此您还可以(取消)直接从/向 pojo 编组。

There's an example (and more info) in the jersey user guide, which I copy here:

球衣用户指南中有一个示例(以及更多信息),我将其复制到此处:

POJO with JAXB annotations:

带有 JAXB 注释的 POJO:

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

Resource:

资源:

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

}      

The xml that gets produced/consumed:

生成/使用的 xml:

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

回答by user2723428

Try this using this single 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 ...

    }
}

The url for try rest services ends .... /serviceX/doSomething

尝试休息服务的 url 结束 .... /serviceX/doSomething