Issue
I'm attempting to send an HTTP request from an AsyncTask
in Android Studio, using the code below.
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;
}
My ResponseBody
class extends InputStream
, so I thought that using
ResponseBody responseBody = (ResponseBody) connection.getInputStream();
would work, but here is the problem:
I'm getting a ClassCastException
in my code, because connection.getInputStream()
returns an object of type com.android.okhttp.okio.RealBufferedSource$1
. Why is getInputStream
not returning InputStream
as per Java documentation? Is this an android-specific issue?
EDIT: I defined the ResponseBody class myself (shown below). It is not the one from okhttp
, and it does extend InputStream
, as far as I can tell.
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;
}
}
Solution
The getInputStream()
method does return an InputStream
. But you are attempting to cast the result to a ResponseBody
. That won't work unless the result object is an instance of a subtype of ResponseBody
... which it isn't.
Now, it is unclear which ResponseBody
class you are trying to use here, but if it is okhttp3.ResponseBody
(javadoc), then you can't obtain it by casting an InputStream
.
I actually defined the
ResponseBody
class myself. It is a simple extension ofInputStream
(see edit), so I seems like the downward cast should work
Ah. I see.
No that won't work. You cannot cast an object to a type that it isn't. That's not what type casts do ... for reference types.
You have an instance of the anonymous inner class
com.android.okhttp.okio.RealBufferedSource$1
which is a subtype of InputStream
. You are trying to cast it to a ResponseBody
which is also a subtype of InputStream
. But ResponseBody
is NOT a superclass or interface of the anonymous class, so the typecast cannot succeed.
I suggest that you rewrite ResponseBody
to be a wrapper class for InputStream
and / or use one of the solutions listed here fro extracting the contents of an InputStream
to a String
:
Answered By - Stephen C
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.