4

我有这个带有几个自定义 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 标头的请求:

接受:text/turtle,application/n-triples;q=0.9,application/rdf+xml;q=0.8,application/xml;q=0.7, / ;q=0.5

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

有没有激活它的选项?

4

2 回答 2

1

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

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

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

于 2014-04-23T10:06:13.920 回答
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对象列表作为请求的一部分,然后使用 aResponseEntity来定义Content-Type您的结果将是什么。这需要多一点思考。

@RequestMapping(value="/sparql/query", method=RequestMethod.GET)
public ResponseEntity<String> queryViaGet(@RequestHeader(value="Accept") final List<MediaType> contentTypes)
{
    MediaType.sortBySpecificityAndQuality(contentTypes);

    // Do some stuff to select your content type and generate your response
    final String results = null;
    final MediaType desiredType = null;

    // Create your REST response
    final HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentType(desiredType);
    return new ResponseEntity<String>(results, responseHeaders, HttpStatus.OK);
}
于 2014-04-23T15:44:08.000 回答