[英]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.