0

我希望创建一个与 XML 以及 JSON 响应兼容的 REST 服务。两者的 URI 相似。我需要根据接受标头提供响应。

这可以通过单个 URI 实现吗?如果可能,我如何设置@Produces?

4

2 回答 2

1

阅读 javadoc 的@Produces

定义资源类或 {@link javax.ws.rs.ext.MessageBodyWriter} 的方法可以生成的媒体类型。* 如果未指定,则容器将假定可以生产任何类型。

这意味着此注释只会减少支持的媒体类型的数量。否则选择会自动完成。

接口MessageBodyWriter有很多不同媒体类型的实现。具体实现选择为MessageBodyFactory

public <T> MediaType getMessageBodyWriterMediaType(Class<T> c, Type t,
        Annotation[] as, List<MediaType> acceptableMediaTypes) {
    for (MediaType acceptable : acceptableMediaTypes) {
        for (MessageBodyWriterPair mbwp : customWriterListProviders) {
            for (MediaType mt : mbwp.types) {
                if (mt.isCompatible(acceptable) &&
                        mbwp.mbw.isWriteable(c, t, as, acceptable)) {
                    return MediaTypes.mostSpecific(mt, acceptable);
                }
            }
        }
        ......................

正如我们所见,acceptableMediaTypes选择了支持第一个的第一个提供者。虽然恕我直言,这个名字acceptableMediaTypes是可以自我解释的,但我继续我的发现并找到了唯一调用此方法的地方:

        contentType = getMessageBodyWorkers().getMessageBodyWriterMediaType(
                    entity.getClass(),
                    entityType,
                    annotations,
                    request.getAcceptableMediaTypes());

其中request的类型是ContainerRequest

这是代码getAcceptableMediaTypes()

public List<MediaType> getAcceptableMediaTypes() {
    if (accept == null || headersModCount != headers.getModCount())
        accept = new ArrayList<MediaType>(HttpHelper.getAccept(this));

    return accept;
}

正如我们所见,媒体类型列表中填充了以下结果HttpHelper.getAccept(this)

final String accept = request.getHeaderValue(HttpHeaders.ACCEPT);

底线:是的,媒体类型是根据 HTTP 标头自动选择的,Accept除非硬编码注释@Produces限制了这一点。

于 2013-09-10T07:01:25.307 回答
0

@Produces({"application/xml", "application/json"})

对于 JAX-RS 实现...

很久以前我使用过它,但我记得——并且可能仍然适用于某些实现——您需要将自定义的 MediaConfig 添加到您的应用程序中。但它绝对是为 JEE6/7 内置的。

那时我定制了尊重请求uri中的文件扩展名......也许标题总是有效的。

编辑:刚刚搜索过,可能不称为 MediaConfig,当我找到/记住它并且仍然需要它时,我会回来。

于 2013-09-10T06:59:48.297 回答