Ich versuche, mit dem folgenden Code ein Token von einem JSON-Endpunkt abzurufen:

public class FetchToken extends AsyncTask<String, Void, Void> {
    String data = "";
    String token = "";

    public TokenDelegate delegate = null;

    @Override
    protected Void doInBackground(String... identity) {
        try {
            if (identity.length == 1) {
                URL url = new URL(identity[0]);

                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String line = "";

                while (line != null) {
                    line = bufferedReader.readLine();
                    data = data + line;
                }

                JSONObject JO = new JSONObject(data);
                token = JO.get("token").toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        Log.d("token", token);
        //delegate.processFinish(token);
        super.onPostExecute(aVoid);
    }
}

Ich habe versucht, nach jeder Zeile in das Debug-Protokoll zu drucken, und es scheint, dass die Zeile InputStream inputStream = httpURLConnection.getInputStream(); nie beendet wird und der Rest des Codes auch nicht ausgeführt wird. Dies findet jedoch innerhalb einer AsyncTask statt, und die onPostExecute-Methode dieser AsyncTask wird ausgelöst, als ob die Aufgabe abgeschlossen worden wäre, was nicht so scheint, als ob sie abgeschlossen wäre.

Wie es scheint, wird keiner der Catch-Blöcke ausgeführt. Wenn ich das Netzwerkfenster im Android Profiler inspiziere, heißt es in der Anfrage, dass nichts zurückgegeben wird. Durch den Zugriff auf den JSON-Endpunkt im Browser wird jedoch alles korrekt wiederhergestellt.

Hoffentlich weiß jemand, was das Problem sein kann. Ich habe versucht, Dinge ohne Erfolg zu googeln. Lassen Sie mich wissen, wenn weitere Informationen benötigt werden. Vielen Dank.

4
Dehodson 17 Apr. 2018 im 19:36

4 Antworten

Beste Antwort

Die Zeile InputStream inputStream = httpURLConnection.getInputStream(); wurde nie abgeschlossen, da sie eine java.security.cert.CertPathValidatorException warf. Der Fehler wurde nicht protokolliert, da ich diese Art von Fehler in meinem try / catch-Block nicht abgefangen habe.

4
Dehodson 17 Apr. 2018 im 18:15

Schauen Sie sich den folgenden Code an und ändern Sie Ihren Code entsprechend.

1) Wenn die Methode GET ist, können Daten oder Header null sein.

Anwendungsbeispiel

 url = <some url>
 Map<String, String> headers = new HashMap<String, String>();       
 headers.put("Content-Type", "application/json");       
 headers.put("Accept", "application/json");

A) GET:

invokeHTTPRequest(url, "GET", headers, null);

B) POST

Student st = new Student();
Gson gson = new Gson();
String jsonReqData = gson.toJson(st);
String resp = invokeHTTPRequest3(url, "POST", headers,  jsonReqData);

Public static String invokeHTTPRequest (String urlString, String-Methode, Map-Header, String-Daten) {

    URL url = null;
    try {
        url = new URL(urlString);
        HttpURLConnection conn = null;
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(10000);

        if (headers != null) {
            for (Map.Entry<String, String> header : headers.entrySet()) {
                conn.setRequestProperty(header.getKey(), header.getValue());
            }
        }



        if (data != null) {
            byte[] postDataBytes = data.toString().getBytes();
            conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
            conn.setDoOutput(true);
            conn.getOutputStream().write(postDataBytes);

        }

        BufferedReader rd = null;

        if(conn.getResponseCode() == 200){
            rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        }
        else{
            rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
        }

        StringBuilder result = new StringBuilder();

        String line;
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }
        rd.close();


        return result.toString();

    } catch (Exception e) {
        //handle exception here
    }

}
3
Devendra Dora 17 Apr. 2018 im 16:53

Sie haben vergessen, connect auf dem HttpUrlConnection aufzurufen:

HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
2
Levi Moreira 17 Apr. 2018 im 16:39

Sie möchten höchstwahrscheinlich Zeitüberschreitungen festlegen, um sicherzustellen, dass die Verbindung fehlschlägt, wenn die externe Ressource nicht rechtzeitig verfügbar ist. Die Werte sind in Millisekunden, z. Eine Zeitüberschreitung von 5 Sekunden für das Verbinden und Lesen wäre:

 HttpURLConnection conn = ...
 conn.setConnectTimeout(5000);
 conn.setReadTimeout(5000);

Standardmäßig sind die Zeitüberschreitungen auf 0 eingestellt. Gemäß setConnectTimeout() bedeutet dies:

Eine Zeitüberschreitung von Null wird als unendliche Zeitüberschreitung interpretiert.

2
Karol Dowbecki 17 Apr. 2018 im 16:44