基于accept参数的REST服务响应

时间:2013-09-10 06:42:55

标签: java rest jersey soapui java-ws

我希望创建一个兼容XML和JSON Response的REST服务。两者的URI相似。我需要根据accept标头提供响应。

这可以使用单个URI吗?如果可能,我如何设置@Produces?

2 个答案:

答案 0 :(得分:1)

阅读@Produces的javadoc:

  

定义资源类或方法的媒体类型   {@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限制了这一点。

答案 1 :(得分:0)

@Produces({“application / xml”,“application / json”})

对于JAX-RS实现......

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

当时我在请求uri中自定义尊重文件扩展名...也许标题始终有效。

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