Почему метод getInputStream () HttpURLConnection возвращает объект типа RealBufferedSource? - PullRequest
0 голосов
/ 31 декабря 2018

Я пытаюсь отправить HTTP-запрос с AsyncTask в Android Studio, используя код ниже.

protected Long doInBackground(URL... urls) {
    try {
        HttpURLConnection connection = (HttpURLConnection) urls[0].openConnection();
        connection.setRequestMethod("POST");
        connection.connect();

        byte[] loginRequestBytes = new Gson().toJson(loginRequest, LoginRequest.class).getBytes();
        connection.getOutputStream().write(loginRequestBytes);

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            ResponseBody responseBody = (ResponseBody) connection.getInputStream(); // ResponseBody extends InputStream
            loginResponse = new Gson().fromJson(responseBody.toString(), LoginResponse.class);
        }
    } catch (IOException e) {
        Log.e("HttpClient", e.getMessage(), e);
    }

    return null;
}

Мой класс ResponseBody расширяется InputStream, поэтому я подумал, что использование

ResponseBody responseBody = (ResponseBody) connection.getInputStream();

будет работать, но вот проблема:

I 'Я получаю ClassCastException в моем коде, потому что connection.getInputStream() возвращает объект типа com.android.okhttp.okio.RealBufferedSource$1.Почему getInputStream не возвращает InputStream согласно документации Java ?Это проблема для Android?

РЕДАКТИРОВАТЬ: Я сам определил класс ResponseBody (показано ниже).Это , а не от okhttp, и оно, насколько я могу судить, распространяется InputStream.

public class ResponseBody extends InputStream {

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        String line;

        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(this, "UTF-8"))) {
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return stringBuilder.toString();
    }

    @Override
    public int read() throws IOException {
        return 0;
    }
}

1 Ответ

0 голосов
/ 31 декабря 2018

Метод getInputStream() возвращает и возвращает InputStream.Но вы пытаетесь привести результат к ResponseBody.Это не сработает, если результирующий объект не является экземпляром подтипа ResponseBody ... который не является.

Теперь неясно, какой класс ResponseBody вы пытаетесь использовать здесь, но если это okhttp3.ResponseBody ( javadoc ), то вы не можете получить его, применив InputStream.


Я сам определил класс ResponseBody.Это простое расширение InputStream (см. Редактирование), поэтому мне кажется, что нисходящий акт должен работать

А-а.Понятно.

Нет, это не сработает.Вы не можете привести объект к типу, которым он не является.Это не то, что делает приведение типов ... для ссылочных типов.

У вас есть экземпляр анонимного внутреннего класса

  com.android.okhttp.okio.RealBufferedSource$1

, который является подтипом InputStream.Вы пытаетесь привести его к ResponseBody, который также является подтипом InputStream.Но ResponseBody НЕ является суперклассом или интерфейсом анонимного класса, поэтому типизация не может быть успешной.

Я предлагаю переписать ResponseBody в класс-оболочку для InputStream и / или использовать один из следующих типов:решения, перечисленные здесь для извлечения содержимого InputStream в String:

...