我目前正在尝试使用 Neo4j 数据库执行 Cypher 查询,作为我为开始和练习使用 REST API 而制作的 Android Studio 应用程序的一部分。其代码如下所示:
public class MainActivity extends AppCompatActivity {
private TextView userText;
private Button clicker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userText = (TextView) findViewById(R.id.txtUsername);
clicker = (Button) findViewById(R.id.btnClick);
clicker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//The REST API needs it's own thread for Neo4j connection. Read up on this documentation.
AsyncTask.execute(new Runnable() {
@Override
public void run() {
try {
//The URL will change based on what is needed for the documentations.
//Provides the address for the HTTP communication.
String neo4jURL = "http://ec2-35-176-79-15.eu-west-2.compute.amazonaws.com:7474/db/data/cypher";
//Helps to create the JSON object used by the query.
//QueryData neo4jqueryData = new QueryData();
//Creates the client used for the connection.
HttpClient neo4jClient = new DefaultHttpClient();
//Assigns the address to either the HttpGet or HttpPost request.
HttpPost neo4jRequest = new HttpPost(neo4jURL);
//Creates the JSON Attributes that will be used as part of the query.
String query = "MATCH (n:Student) WHERE n.Username=\'cs16thm\' RETURN n.StudentID";
JSONObject neo4jJSON = new JSONObject();
neo4jJSON.put("query",query);
neo4jJSON.put("params","");;
String check = neo4jJSON.toString();
Log.d("JSON",check);
StringEntity queryString = new StringEntity(check,"UTF-8");
//Ensures that the application type is JSON.
queryString.setContentType("application/json");
//Adds the Attribute data to the JSON query.
neo4jRequest.setEntity(queryString);
//Adds the Headers to the query.
//bmVvNGo6Z3JvdXAzNw== is the Base64 encoding of the username and password.
neo4jRequest.setHeader("Authorization","Basic bmVvNGo6Z3JvdXAzNw==");
//Shows the data types that would be accepted by the query result.
neo4jRequest.setHeader("Accept", "application/json; charset=UTF-8");
//Used to show the data type being sent to the server.
neo4jRequest.setHeader("Content-Type", "application/json");
Log.d("Check-Type",neo4jRequest.getEntity().toString());
//Performs the neo4j query.
HttpResponse queryResult = neo4jClient.execute(neo4jRequest);
//Checks the status code of the request.
int statusCode = queryResult.getStatusLine().getStatusCode();
if (statusCode == 200 || statusCode == 400){
Log.d("CONNECT","Query Made");
//Gets the results stream from the connection. Results is returned as a JSON which needs to be parsed.
InputStreamReader resultsReader = new InputStreamReader(queryResult.getEntity().getContent());
JsonReader JsonReader = new JsonReader(resultsReader);
//Begins processing of the JSON results.
JsonReader.beginObject();
//Checks all of the parameter keys returned by the document.
Log.d("RESULT","Begin JSON Parse");
while(JsonReader.hasNext()){
//Gathers the name of the current key.
String resultKey = JsonReader.nextName();
//Checks if it's the data we're looking for.
if(resultKey.equals("message")){
//Gathers the String value that we require.
String result = JsonReader.nextString();
//Shows the result in the application.
Log.d("RESULT","Result=" + result);
//Prevents further loop execution now that our data is retrieved.
break;
} else {
//Skips to the next value if the current one contains nothing of interest.
JsonReader.skipValue();
}
}
Log.d("RESULT","End JSON Parse");
//Closes the JSON reader after task to prevent resource hogging.
JsonReader.close();
} else {
Log.d("ERROR", "Request not made " + Integer.toString(statusCode));
}
} catch (MalformedURLException e) {
e.printStackTrace();
Log.d("ERROR", "Bad URL");
} catch (IOException ioe) {
ioe.printStackTrace();
Log.d("ERROR", "Cannot Connect");
} catch (Exception par){
par.printStackTrace();
Log.d("ERROR", "Parse Fail");
}
}
});
}
});
}
}
虽然我的程序成功接收到来自 Neo4j Amazon EC2 服务器的响应,但它会回复 HTTP 400 错误并提供以下错误消息,这些消息出现在输出 JSON 字符串中:Result=Parameters must be a JSON map
, Result=IllegalArgumentException
, Result=java.lang.IllegalArgumentException
由于这些消息,我尝试确保我的查询实体采用有效的 JSON 格式,但尽管如此,错误消息似乎仍然出现。尽管在互联网资源中进行了大量搜索,但我一直无法找到该问题的解决方案。我目前正在使用 Apache HttpClient 和 Google 的 Simple JSON 外部库。
如果有人能够提供任何见解或解决方案来帮助我解决这个问题,我将不胜感激。我也有兴趣查看任何其他可以建立我的 REST API 连接的 Java 代码。但是,我可以确认 Neo4j 提供的许多官方驱动程序,例如当尝试通过 Bolt 协议(protocol)连接时,Neo4j-Java-Driver 似乎与 Android Studio 不兼容。最后,如果您还有其他问题想问我,请随时提问。
更新:
按照 cybersam 建议省略“params”值确实可以解决错误并为成功查询生成 HTTP 200 代码。但是,当我尝试通过将行 if(resultKey.equals("message")) 更改为 if(resultKey.equals("data")) 来读取 Neo4j 提供的 JSON 文件作为查询结果时,我收到以下错误消息: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY throwed on the line String result = JsonReader.nextString();以及 ParseException。 Neo4j 文档说,JSON 文件应采用类似于以下的格式: { "columns": [ "n.StudentID"], "data": ["1607174"] }
最佳答案
您当前正在将 ""
设置为 params
的值。由于 ""
不是 JSON 映射,因此您会收到该错误。
您可以将 {}
设置为 params
的值,或者更好的是,直接省略 params
字段的整个 put
语句,因为该字段是可选的。
关于java - 尝试在 Java 中进行 REST API Cypher 查询时如何解决 neo4j 错误(参数必须是 JSON 映射),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48467458/