Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple response types with same REST GET?

Tags:

java

rest

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

like image 348
markthegrea Avatar asked Jun 24 '10 13:06

markthegrea


People also ask

Can I send multiple responses for a single request?

No. In http, one request gets one response. The client must send a second request to get a second response.

How does angular handle multiple responses?

To log response or to perform any side effects, use tap operator. In case, if you are using APIResponse variable and want to assign response to it, you have to do it in tap operator as this is side effect. Finally, to get data from server, subscribe to getData() observable stream in your component.


2 Answers

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.

like image 114
Bruno Avatar answered Oct 06 '22 19:10

Bruno


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

like image 44
Soumya Avatar answered Oct 06 '22 20:10

Soumya