繁体   English   中英

Restlet内容类型协商

[英]Restlet Content Type Negotiation

API支持各种形式的内容协商是很常见的: Accept Request上的Request, Content-Type HTTP标头上的HTTP标头(尽管我认为不符合标准),并从文件扩展名中获取预期的类型。 我希望我的Restlet REST API支持所有这些,我正在寻找帮助来弄清楚如何做到这一点。

我的第一个努力是看看Restlet是否支持开箱即用。 我正在使用Jackson扩展,所以我创建了一个简单的应用程序,它将/foo路由到返回Map<String,Boolean>ServerResource

当我只是将GET HTTP URL连接(la https://stackoverflow.com/a/953697/27561 )连接到/foo ,我得到了XML。 我想这个默认为JSON。 这是问题#1。 如何制作默认类型JSON?

当我对/foo.xml/foo.json进行相同的HTTP URL连接调用时,我得到一个404.那就是问题#2。 如何使用文件扩展名表示预期的媒体类型?

由于我在Servlet容器中运行,我当前的方法是包装HttpServletRequest ,并在没有文件扩展名的情况下将Accept HTTP标头设置为application/json 这是一个正在解决问题#1的黑客。 但是,我无法以摆脱问题#2中的404的方式扩展这种方法。

Restlet让很多其他东西变得容易,我假设我错过了一些东西 - 有些问题我可以调整某些配置以使其做正确的事情。 我在API文档中看到过这方面的提示,但没有什么明显的。 那个配置是​​什么?

最简单的方法是在应用程序的路由器前添加自定义过滤器,以执行以下操作:

  • 如果接受的媒体类型列表为空( request.clientInfo.acceptedMediaTypes ),则设置默认媒体类型。 标题Accept的值在此处设置。 在执行服务器资源之前设置它是很重要的,这样可以在从bean到表示的转换过程中考虑到这一点。

     Filter preferencesFilter = new Filter(getContext()) { protected int beforeHandle(Request request, Response response) { if (request.getClientInfo().getAcceptedMediaTypes().isEmpty()) { request.getClientInfo().accept(MediaType.APPLICATION_JSON); } else if ((request.getClientInfo().getAcceptedMediaTypes().size() == 1) && (request.getClientInfo().getAcceptedMediaTypes().get(0).getMetadata().equals(MediaType.ALL))) { request.getClientInfo().accept(MediaType.APPLICATION_JSON); } return super.beforeHandle(request, response); } } 

    有关信息,当指定不接受媒体类型时,Restlet使用已注册的转换器的第一个转换器来实际构建响应内容。 在您的情况下,它似乎是XML。

  • 检测提供的扩展以在您的情况下推断相应的已接受媒体类型。 Restlet的TunnelService允许预处理请求以支持诸如使用扩展进行内容协商之类的功能。 您可以按照以下说明进行简单配置:

     public class MyApplication extends Application { public MyApplication() { getTunnelService().setExtensionsTunnel(true); } @Override public Restlet createInboundRoot() { (...) } } 

否则,在使用Restlet时不应该依赖servlet API。 servlet扩展只应被视为在servlet容器中嵌入Restlet应用程序的适配器......

它在以下地址为您的用例添加了一个示例项目: https//github.com/templth/restlet-stackoverflow/tree/master/restlet/test-restlet-conneg

希望它对你有帮助,蒂埃里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM