Redmine Java Api - org.json.JSONException: A JSONO

2020-08-01 06:08发布

问题:

When I try run this code (The Issue example is taken from this web http://www.redmine.org/projects/redmine/wiki/Rest_api_with_java ) :

    RedmineManager redmineManager = new RedmineManager("http://something.cz", "somekey"); //I changed these two parameters for security reasons when paste here
    System.out.println(redmineManager.getProjects().size()); //this works fine
    Issue issueToCreate = new Issue();
    issueToCreate.setSubject("This is the summary line 123");
    Issue newIssue = redmineManager.createIssue("test-project", issueToCreate); //this line throws exception

It ends with this exception

Exception in thread "main" com.taskadapter.redmineapi.RedmineFormatException: org.json.JSONException: A JSONObject text must begin with '{' at character 1
    at com.taskadapter.redmineapi.internal.Transport.parseResponse(Transport.java:456)
    at com.taskadapter.redmineapi.internal.Transport.addObject(Transport.java:186)
    at com.taskadapter.redmineapi.RedmineManager.createIssue(RedmineManager.java:135)
    at javaapplication146.JavaApplication146.main(JavaApplication146.java:27)
Caused by: org.json.JSONException: A JSONObject text must begin with '{' at character 1
    at org.json.JSONTokener.syntaxError(JSONTokener.java:410)
    at org.json.JSONObject.<init>(JSONObject.java:179)
    at org.json.JSONObject.<init>(JSONObject.java:402)
    at com.taskadapter.redmineapi.internal.RedmineJSONParser.getResponseSingleObject(RedmineJSONParser.java:609)
    at com.taskadapter.redmineapi.internal.Transport.parseResponse(Transport.java:454)
    ... 3 more
Java Result: 1

The same behaviour is for any other "get some objects" (which works) and for "create some objects" (which does not).

I am using maven ( http://mvnrepository.com/artifact/com.taskadapter/redmine-java-api ) with its dependency for version 1.23, however I tried 1.12.0 and same exception was thrown.

We are using latest redmine 2.5.1.stable, however based on stacktrace, the communication between redmine web and this redmine api does not happen as the exception is thrown in "parseRespone" part of application.

回答1:

Unfortunatelly, it looks like this issue remains unsolve (or unsolvable), based on discussion with library owner : https://github.com/taskadapter/redmine-java-api/issues/126

However GET requests work. And for UPDATE/CREATE, you can use pure API like following. WARNING : Disabling SSL is dangerous, use only for testing purposes (like "does it even work?")

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

/**
 *
 * @author libik
 */
public class JavaApplication147 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        disableCertificateValidation();        

        URL url = new URL("https://redmine.***.cz/issues.xml");
        HttpsURLConnection httpCon = (HttpsURLConnection) url.openConnection();
        httpCon.setRequestProperty("X-Redmine-API-Key", "*****");
        httpCon.setRequestProperty("Content-Type", "application/xml");
        httpCon.setDoOutput(true);
        httpCon.setRequestMethod("POST");
        OutputStreamWriter out = new OutputStreamWriter(
                httpCon.getOutputStream());
        out.write("<?xml version=\"1.0\"?>\n" +
"<issue>\n" +
"  <project_id>pan-unicorn-bot</project_id>\n" +
"  <subject>Created from netbeans by name without priority</subject>\n" +
"</issue>");
        out.close();

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        System.out.println(sb.toString());
    }

    public static void disableCertificateValidation() {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }};

        // Ignore differences between given hostname and certificate hostname
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(hv);
        } catch (Exception e) {
        }
    }

}