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:
It also works via the extension (thanks to getTunnelService().setExtensionsTunnel(true)
):
There's a default list of extension to media-type mapping, but this can be configured via the MetadataService.