Java 具有相同 REST GET 的多种响应类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3110239/
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-13 16:31:30  来源:igfitidea点击:

Multiple response types with same REST GET?

javarest

提问by markthegrea

I want to create a REST service that can return either JSON or XML. What request parameter do I set in the request to request a certain mime type? I know how to set it in the response, but there must be a way to request a certain one. Currently I do it in the URL

我想创建一个可以返回 JSON 或 XML 的 REST 服务。我在请求中设置什么请求参数来请求某种 MIME 类型?我知道如何在响应中设置它,但必须有一种方法来请求某个特定的。目前我在 URL 中执行此操作

restServlet/engine/2WS2345

restServlet/引擎/2WS2345

jsonServlet/engine/2WS2345

jsonServlet/引擎/2WS2345

This gets me json or xml. But I thought I read that there is a parameter to set in the request. I am using JAVA...

这让我得到 json 或 xml。但我想我读到有一个参数需要在请求中设置。我正在使用JAVA...

采纳答案by Soumya

If you are using jersey you can easily configure the method with @Produces annotation. @Produces({"application/xml", "application/json"})

如果您使用 jersey,您可以使用 @Produces 注释轻松配置该方法。@Produces({"application/xml", "application/json"})

Good thing is you can still have a JAXB object as a return type. It will automatically be changed to the required format. Unless MIME type is specified in the Accept Header it will always send xml in the above case.

好消息是您仍然可以将 JAXB 对象作为返回类型。它将自动更改为所需的格式。除非在 Accept Header 中指定 MIME 类型,否则在上述情况下它将始终发送 xml。

Ref http://jersey.java.net/nonav/documentation/1.6/user-guide.html

参考http://jersey.java.net/nonav/documentation/1.6/user-guide.html

回答by Bruno

You can do this with Restletusing annotations in your code and either let the content-negotiation operate depending on the user-agent's Acceptheader or specify the extension in the URI (using Restlet's TunnelService and MetadataService). Here is an example (based on Restlet 2):

您可以使用Restlet在代码中使用注释来完成此操作,并让内容协商根据用户代理的Accept标头进行操作或在 URI 中指定扩展名(使用 Restlet 的 TunnelService 和 MetadataService)。这是一个示例(基于 Restlet 2):

public class TestApplication extends Application {
    public static class TestResource extends ServerResource {
        @Get("txt")
        public Representation toText() {
            return new StringRepresentation("Hello!",
                MediaType.TEXT_PLAIN);
        }

        @Get("xml")
        public Representation toXml() {
            return new StringRepresentation("<test>Hello</test>",
                MediaType.APPLICATION_XML);
        }
    }

    @Override
    public synchronized Restlet createInboundRoot() {
        getTunnelService().setEnabled(true);
        getTunnelService().setExtensionsTunnel(true);
        Router router = new Router();
        router.attachDefault(TestResource.class);
        return router;
    }

    public static void main(String[] args) throws Exception {
        Component component = new Component();
        component.getServers().add(Protocol.HTTP, 8182);
        component.getDefaultHost().attachDefault(new TestApplication());
        component.start();
    }
}

Content-negotiation works via the Accept header:

内容协商通过 Accept 标头工作:

  • curl -H "Accept: text/plain" http://localhost:8182/testreturns Hello!
  • curl -H "Accept: application/xml" http://localhost:8182/testreturns <test>Hello</test>
  • curl -H "Accept: text/plain" http://localhost:8182/test返回 Hello!
  • curl -H "Accept: application/xml" http://localhost:8182/test返回 <test>Hello</test>

It also works via the extension (thanks to getTunnelService().setExtensionsTunnel(true)):

它也可以通过扩展工作(感谢getTunnelService().setExtensionsTunnel(true)):

  • curl http://localhost:8182/test.txtreturns Hello!
  • curl http://localhost:8182/test.xmlreturns <test>Hello</test>
  • curl http://localhost:8182/test.txt返回 Hello!
  • curl http://localhost:8182/test.xml返回 <test>Hello</test>

There's a default list of extension to media-type mapping, but this can be configured via the MetadataService.

媒体类型映射有一个默认的扩展列表,但这可以通过 MetadataService 进行配置。