内容协商:如何从接受标题中提供除最高排名类型以外的服务

时间:2014-04-23 09:52:05

标签: java spring jena content-negotiation

我有几个自定义HttpMessageConverters的Spring Java配置:

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorParameter(true).
            ignoreAcceptHeader(false).
            useJaf(true).
            defaultContentType(MediaType.TEXT_HTML).
            mediaType("html", MediaType.TEXT__HTML).
            mediaType("rdf", MediaTypes.RDFXML);
}

如果我使用Jena查询此设置,则会收到错误消息:

  

此请求标识的资源只能生成   根据请求具有不可接受的特征的回复   “接受”标题

Jena使用此Accept标头发送请求:

  

接受:   文本/龟,应用/正三元组; Q = 0.9,应用/ RDF + xml的; Q = 0.8,应用/ XML; Q = 0.7, / 的; Q = 0.5

根据我的理解,application/rdf+xml应该由上面的配置返回。只要配置了具有最高值的类型,这就完美地工作。为什么Spring没有回归到0.8值application/rdf+xml,因为text/turtleapplication/n-triples不可用?

是否可以选择激活它?

2 个答案:

答案 0 :(得分:1)

ContentNegotiationConfigurer.mediaType(String,MediaType)适用于请求解析并定义从扩展到媒体类型的映射 - 如果请求未以Accept标头的形式定义显式媒体类型,但请求路径结束使用指定的扩展名,假定指定的媒体类型。

基本上,ContentNegotiationConfigurer可以丰富(或修改)请求数据,但不会选择实际的响应类型。

您需要的是一个控制器,它可以生成多种媒体类型或多个控制器(或同一控制器中的多个方法),这些控制器可以生成不同的媒体类型,application/rdf+xml就是其中之一。如果application/rdf+xml是请求中(可能是富集或修改的)Accept标头与控制器实际生成的标头之间的最高公共媒体类型,Spring将自动选择该控制器。

答案 1 :(得分:1)

我通过定义不同的MVC处理程序,或通过反映内容类型然后决定返回什么来实现这一目标。

定义不同的处理程序

如果您指定@RequestMapping produces某个值,那么这将是Content-Type标题上的类型,无论在哪里引导您的请求的自动协商。你可以强迫'作为唯一可以回答的人,向这些处理者提出请求。我使用它来返回更具体的类型,但我怀疑你也可以使用它来返回更通用的类型。

@RequestMapping(value="/sparql/service", produces={"application/rdf+xml;charset=utf-8", MediaType.ALL_VALUE})
public @ResponseBody String serviceDescriptionAsRdfXml()
{
    return null; // something here
}

@RequestMapping( value="/sparql/service", produces={"text/turtle;charset=utf-8"} )
public @ResponseBody String serviceDescriptionAsTurtle( final HttpServletRequest request )
{
    return null; // something here
}

反思内容类型

要反思进入的类型并生成更通用的内容,那么您实际上可以在请求中检索MediaType个对象的列表,然后使用ResponseEntity来定义{ {1}}将用于您的结果。这需要多一点思考。

Content-Type