本文介绍了JAX-RS/Jersey 中的 HTTP 内容协商冲突?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢 JAX-RS(特别是 Jersey)的自动 HTTP 内容协商,即它能够通过Accept"和/或Content-Type"标头路由我的资源.但我发现有时在发生冲突时它并没有给我足够的控制权.

I am enjoying the auto HTTP content negotiation of JAX-RS (specifically Jersey), i.e. its ability to route my resources by "Accept" and/or "Content-Type" headers. But I'm finding that sometimes it doesn't give me enough control when there is a conflict.

例如,考虑以下端点:

@Path("/order")
public class OrderController {

    @GET
    @Path("{orderID: \d+}")
    @Produces("text/html")
    public View getOrderView(@PathParam("orderID") long id) {
        Order order = this.getOrderData(id);
        return new OrderView(order);
    }

    @GET
    @Path("{orderID: \d+}")
    @Produces({"application/json", "application/xml"})
    public Order getOrderData(@PathParam("orderID") long id) {
        return new OrderService.findOrder(id);
    }
}

我会在 Firefox 和 Chrome 之间得到不同的结果.Firefox 将映射到 HTML 端点,而 Chrome 将在我导航到每个端点 URL 时触发 XML 端点.它们之间的区别在于其 Accept 标头中列出的 MIME 类型的顺序.Chrome 发送以下内容:

I will get different results between Firefox and Chrome. Firefox will map to the HTML endpoint while Chrome will trigger the XML endpoint when I navigate each to the endpoint URL. The difference between them is the order of the listed MIME types in their Accept headers. Chrome sends the following:

User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.107 Safari/534.13
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

与 Firefox 相比,它首先列出 HTML:

Versus in Firefox it lists HTML first:

User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

当所有的权重相同时,它会匹配第一个条目,这似乎是合乎逻辑的.但就我而言,我得到的结果与我想要的不同,因此最好确定一种更好的打破平局的方法.

Seems logical that it would match the first entry when all are weighted the same. But in my case I am getting the different results than I want so it would be nice to determine a better method for tie-breaking.

我的问题:没有将标头信息注入这些方法并自己执行媒体类型处理,有没有办法在出现平局时调整权重"?例如,我可以告诉它总是用 HTML 胜过 XML 吗?我的 RESTful 客户端对他们想要返回的类型非常明确,但浏览器对 Accept 标头的草率是出了名的.(我个人认为他们应该将 HTML 的权重略高于 XML,因为这是用户所期望的,但这有点晚了.)

My question: short of injecting header information into these methods and performing the media type processing myself, is there a way to "tweak the weights" so to speak in the event of a tie? For instance, can I tell it to always trump XML with HTML? My RESTful clients are very explicit about what type they want back but browsers are notoriously sloppy with Accept headers. (Personally I think they should weight HTML slightly above XML as this is what users expect but it's a little late for that.)

或者,我可以在某个集中位置只执行一次我自己的自定义内容协商吗?我不反对手动写出这个逻辑,但如果这意味着将它应用到我的资源的每一个实例上,我就不反对了.JAX-RS 是否有一些概念,即在管道中添加过滤器以在请求被路由之前对其进行调整?

Alternatively, can I perform my own custom content negotiation only once in some centralized location? I'm not opposed to writing this logic out manually but not if it means applying it to every single instance of my resources. Does JAX-RS have some concept of adding a filter to the pipeline to tweak requests before they are routed?

推荐答案

作为泽西岛 用户指南声明:

如果两者都同样可接受,则将选择前者,因为它首先出现.

据我所知,这给你留下了两种可能性/黑客:

From what I know, this leaves you with two possibilities/hacks:

  1. 将文件扩展名附加到您的用于覆盖 Accept 标头的 URI

  1. Append the file extension to yourURIs to override the Accept header

编写一个 servlet 过滤器覆盖 Accept 标头那些用户代理

Write a servlet filter thatoverwrites the Accept header forthose User Agents

这篇关于JAX-RS/Jersey 中的 HTTP 内容协商冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-18 18:32
查看更多