简体   繁体   English

尝试使用Java进行REST API密码查询时如何解决neo4j错误(参数必须为JSON映射)

[英]How to resolve neo4j error (Parameters Must be a JSON Map) when attempting to make an REST API Cypher query in Java

I am currently attempting to perform a Cypher query with my neo4j database as part of an Android Studio application I have made to get started and practise using the REST API. 我目前正在尝试对我的neo4j数据库执行Cypher查询,作为开始并练习使用REST API的Android Studio应用程序的一部分。 The code for which is shown below: 其代码如下所示:

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");
                    }
                }
            });
        }
    });
}
}

While my program does successfully receive a response from my neo4j Amazon EC2 server, it replies with an HTTP 400 error and provides the following error messages, present within the output JSON string: Result=Parameters must be a JSON map , Result=IllegalArgumentException , Result=java.lang.IllegalArgumentException 当我的程序确实从我的neo4j Amazon EC2服务器成功接收到响应时,它会回复HTTP 400错误并提供以下错误消息,这些消息出现在输出JSON字符串中: Result=Parameters must be a JSON mapResult=IllegalArgumentExceptionResult=java.lang.IllegalArgumentException

Due to these messages, I tried to ensure that my query entity is in the valid JSON format, but despite this, the error message still seems to appear. 由于这些消息,我试图确保我的查询实体采用有效的JSON格式,但是尽管如此,错误消息似乎仍然出现。 Despite a significant amount of searching throughout internet sources, I have been unable to find a solution to this problem. 尽管在整个Internet资源中进行了大量搜索,但我仍无法找到解决该问题的方法。 I am currently using the Apache HttpClient and Google's Simple JSON external libraries. 我目前正在使用Apache HttpClient和Google的Simple JSON外部库。

I would be grateful if anyone could offer any insight or solutions that would help me solve this problem. 如果有人可以提供任何能帮助我解决此问题的见解或解决方案,我将不胜感激。 I would also be interested in seeing any other Java code that could make my REST API connection. 我还将对看到任何其他可以建立我的REST API连接的Java代码感兴趣。 However, I can confirm that many of the official drivers offered by Neo4j, eg Neo4j-Java-Driver don't seem to be compatible with Android Studio when trying to connect through the Bolt protocol. 但是,我可以确认Neo4j提供的许多官方驱动程序,例如Neo4j-Java-Driver在尝试通过Bolt协议进行连接时似乎与Android Studio不兼容。 Finally, if you have any further questions for me please feel free to ask. 最后,如果您还有其他疑问,请随时提出。

UPDATED: 更新:
Omitting the 'params' value as suggested by cybersam does solve the error and produce an HTTP 200 code for a successful query. 取消Cyber​​sam建议的'params'值确实可以解决该错误,并为成功查询生成HTTP 200代码。 However when I try to read the JSON file provided by Neo4j as a query result by changing the line if(resultKey.equals("message")) to if(resultKey.equals("data")), I receive the following error message: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY thrown on the line String result = JsonReader.nextString(); 但是,当我尝试通过将if(resultKey.equals(“ message”))行更改为if(resultKey.equals(“ data”))来读取Neo4j提供的JSON文件作为查询结果时,收到以下错误消息:java.lang.IllegalStateException:需要一个字符串,但是在行String result = JsonReader.nextString();上引发了BEGIN_ARRAY along with a ParseException. 以及ParseException。 Neo4j docs say, the JSON file should take a format similar to this: { "columns" : [ "n.StudentID" ], "data" : ["1607174"] } Neo4j文档说,JSON文件应采用类似于以下格式:{“ columns”:[“ n.StudentID”],“ data”:[“ 1607174”]}

You are currently setting "" as the value of params . 您当前正在将""设置为params的值。 Since "" is not a JSON map, you are getting that error. 由于""不是JSON映射,因此您会收到该错误。

You can either set {} as the value of params , or, even better, just omit the entire put statement for the params field since that field is optional. 您可以将{}设置为params的值,或者甚至更好,因为params字段是可选的,所以只需省略整个put语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM