google / google/volley

Allow sending any JSON with JsonArrayRequest and JsonObjectRequest

Open
#419 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
3.4k
Forks
751
Avg merge
8h 49m
Merged PRs (30d)
2

Description

Prior to #406, JsonArrayRequest required JSONArray request bodies, and JsonObjectRequest required JSONObject request bodies. Nothing should couple the request type and response type, so it's reasonable to want to send JSONObjects and get back JSONArray, or vice versa. However, the new constructors can end up breaking compilation of existing code which depend on Volley, since the request argument is nullable and thus ambiguous if null is provided. For example, code like:

```java
JsonObjectRequest request = new JsonObjectRequest(Method.POST, url, null, listener, errorListener);
```

compiles fine with the current Volley production release, but suddenly fails to compile here since the compiler doesn't know whether this corresponds to the JSONObject or JSONArray constructor.

I don't see a great, backwards-compatible fix for this. Adding a factory method or builder isn't sufficient because subclassing the request is fairly common too (e.g. to populate custom headers). We could just reorder the arguments in one of them, but that would just make for a more confusing API.

So I think for the short term, we should just revert back to what was in place before. Longer term, if/when we make breaking API changes, we can consider improvements here.

The workaround is to extend JsonRequest directly, e.g.:

```java
public class MyJsonObjectRequest extends JsonRequest {
public MyJsonObjectRequest(..., JSONArray request, ...) {
super(..., request != null ? request.toString() : null, ...);
}

@Override
protected Response parseNetworkResponse(NetworkResponse response) {
try {
String jsonString =
new String(
response.data,
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
return Response.success(
new JSONObject(jsonString), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
}
```

or just avoid using these classes entirely - they're not that complex, and you're probably better off using a strongly-typed JSON object instead.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.