Apache Jena 4.9.0执行SPARQL SELECT查询遇Content-Type报错求助
问题:Apache Jena 4.9.0调用SPARQL端点返回Content-Type不被识别错误
使用Apache Jena 4.9.0开发工具,向Virtuoso开源版7.2.13和GraphDB 10.8.0的SPARQL端点发送SELECT查询时,触发错误:
Endpoint returned Content-Type: application/sparql-results+json which is not recognized for SELECT queries.
代码实现
HttpClient httpClient = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(shortTimeOut)) .followRedirects(Redirect.NORMAL) .build(); QueryExecution gqexec = QueryExecutionHTTPBuilder .service(ep) .httpClient(httpClient) .query(q) .sendMode(QuerySendMode.asPost) .timeout(longTimeOut, TimeUnit.SECONDS) .build(); ResultSet rs = gqexec.execSelect();
查询语句
SELECT DISTINCT ?g WHERE { GRAPH ?g {?s ?p ?o} }
请求详情
Received POST request: POST /sparql HTTP/1.1 Headers: Connection: Upgrade, HTTP2-Settings Content-Length: 48 Host: localhost:8080 HTTP2-Settings: AAEAAEAAAAIAAAAAAAMAAAAAAAQBAAAAAAUAAEAAAAYABgAA Upgrade: h2c User-Agent: Java-http-client/21.0.5 Accept: application/sparql-results+json, application/sparql-results+xml;q=0.9, text/tab-separated-values;q=0.7, text/csv;q=0.5,application/json;q=0.2,application/xml;q=0.2,*/*;q=0.1 Content-Type: application/sparql-query;charset=utf-8 Body: SELECT DISTINCT ?g WHERE { GRAPH ?g {?s ?p ?o} }
响应数据
< HTTP/1.1 200 OK < Server: Virtuoso/07.20.3240 (Linux) x86_64-ubuntu_focal-linux-gnu < Connection: Keep-Alive < Date: Wed, 27 Nov 2024 09:13:32 GMT < Accept-Ranges: bytes < Content-disposition: filename=sparql_2024-11-27_09-13-32Z.json < Content-Type: application/sparql-results+json < Content-Length: 12180 < { [12180 bytes data] { "head": { "link": [], "vars": ["g"] }, "results": { "distinct": false, "ordered": true, "bindings": [ { "g": { "type": "uri", "value": "http://www.openlinksw.com/schemas/virtrdf#" }}, { "g": { "type": "uri", "value": "http://www.w3.org/ns/ldp#" }}, ...
原因分析
application/sparql-results+json是SPARQL SELECT查询的标准响应Content-Type,报错核心原因包括:
- 自定义HttpClient的配置干扰了Jena默认的响应解析逻辑,导致无法正确识别标准Content-Type;
- Jena 4.9.0对带有
Content-disposition头的响应可能存在解析异常; - 项目依赖缺失
jena-sparql-json模块,导致JSON结果解析器未注册。
解决方法
方法1:强制指定结果格式
在构建QueryExecution时手动指定结果格式为JSON,跳过Content-Type自动检测:
QueryExecution gqexec = QueryExecutionHTTPBuilder .service(ep) .httpClient(httpClient) .query(q) .sendMode(QuerySendMode.asPost) .timeout(longTimeOut, TimeUnit.SECONDS) .format(ResultsFormat.FMT_RS_JSON) // 新增此行 .build();
方法2:使用Jena默认HttpClient
移除自定义HttpClient,使用Jena自带客户端避免配置冲突:
QueryExecution gqexec = QueryExecutionHTTPBuilder .service(ep) .query(q) .sendMode(QuerySendMode.asPost) .timeout(longTimeOut, TimeUnit.SECONDS) .build();
方法3:补全依赖
确保项目依赖中包含jena-sparql-json模块(Maven示例):
<dependency> <groupId>org.apache.jena</groupId> <artifactId>jena-sparql-json</artifactId> <version>4.9.0</version> </dependency>
方法4:针对Virtuoso的额外配置
若仅Virtuoso端点出现问题,可在请求URL后追加format=json参数强制指定返回格式:
QueryExecution gqexec = QueryExecutionHTTPBuilder .service(ep + "?format=json") // 追加参数 .httpClient(httpClient) .query(q) .sendMode(QuerySendMode.asPost) .timeout(longTimeOut, TimeUnit.SECONDS) .build();
内容的提问来源于stack exchange,提问作者Yasunori
相关产品推荐
相关产品推荐

