Jena调用DBpedia SPARQL端点返回text/html不识别SELECT查询问题
问题成因
你遇到的报错本质是公共DBpedia SPARQL端点的GET请求长度限制触发的:
- Apache Jena默认使用GET方法提交SPARQL查询,查询内容会直接拼接在请求URL中。当你循环拼接14次UNION子句后,整个请求URL长度超过了DBpedia端点的GET请求长度限制(通常为8KB左右),服务器会返回格式为
text/html的错误提示页面(如414 URI Too Long错误页),而非Jena预期的SPARQL结果格式(application/sparql-results+xml或application/sparql-results+json),因此触发类型不匹配的异常。 - 循环13次UNION时查询长度未超过限制,因此可以正常执行;浏览器端SPARQL UI默认使用POST方法提交查询,查询内容放在请求体中不受URL长度限制,因此14次UNION的查询也可以正常返回结果。
解决方案
方案1:强制Jena使用POST方法提交查询
直接构造QueryEngineHTTP对象,手动开启POST提交,规避URL长度限制,示例代码如下:
String part = "{<http://dbpedia.org/resource/Marcus_Garvey__Sound__1>?a?v}"; String queryStr = "SELECT DISTINCT ?a?v WHERE {" + part; for (int i = 1; i <= 14; i++) { queryStr += "UNION " + part; } queryStr += "}"; Query query = QueryFactory.create(queryStr); try (QueryEngineHTTP qexec = new QueryEngineHTTP("http://dbpedia.org/sparql", query)) { qexec.setPost(true); // 强制使用POST提交查询 ResultSet resultSet = qexec.execSelect(); while (resultSet.hasNext()) { QuerySolution qs = resultSet.next(); qs.varNames().forEachRemaining(name -> System.out.println(name + "\t" + qs.get(name))); } }
注意使用try-with-resources语法自动释放查询连接资源。
方案2:优化SPARQL查询结构
你当前的查询是重复查询同一个资源的所有属性,完全可以用VALUES语法替代大量重复的UNION子句,大幅缩短查询长度,同时提升查询性能:
SELECT DISTINCT ?a ?v WHERE { # 如果需要查询多个资源,直接放到VALUES的列表中即可 VALUES ?s { <http://dbpedia.org/resource/Marcus_Garvey__Sound__1> } ?s ?a ?v }
内容的提问来源于stack exchange,提问作者Arturs
相关产品推荐
相关产品推荐

