Multiple response types with same REST GET?

2019-06-18 07:02发布

问题:

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

restServlet/engine/2WS2345

jsonServlet/engine/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...

回答1:

If you are using jersey you can easily configure the method with @Produces annotation. @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.

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



回答2:

You can do this with Restlet using annotations in your code and either let the content-negotiation operate depending on the user-agent's Accept header or specify the extension in the URI (using Restlet's TunnelService and MetadataService). Here is an example (based on 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:

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

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

  • curl http://localhost:8182/test.txt returns Hello!
  • curl http://localhost:8182/test.xml returns <test>Hello</test>

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



标签: java rest