I'm using the Java library Volley to do my network requests.
For POST I wanted to use the JsonArrayRequest
class, but I noticed that due to the internal transformation of the JSON array to a string with toString()
, all slashes ocurring in JSON arrays are escaped such that the outcoming string is "\/"
instead of "/"
.
As my JSON arrays contain strings with slashes, I copied and pasted the original JsonArrayRequest class, renamed it and added .replaceAll("\\\\","")
in order to remove all backslashes from the string genereated by toString()
.
It works as it should.
This is the Java code:
public class MyJsonArrayRequest extends JsonRequest<JSONArray> {
public MyJsonArrayRequest(
String url, Listener<JSONArray> listener, @Nullable ErrorListener errorListener) {
super(Method.GET, url, null, listener, errorListener);
}
public MyJsonArrayRequest(
int method,
String url,
@Nullable JSONArray jsonRequest,
Listener<JSONArray> listener,
@Nullable ErrorListener errorListener) {
super(
method,
url,
jsonRequest.toString().replaceAll("\\\\",""),
listener,
errorListener);
}
@Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString =
new String(
response.data,
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
return Response.success(
new JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
}
However, as I'm using Kotlin on my project I prefer to translate the Java code into Kotlin code (I know that Java classes work well with Kotlin, it's just a preference and some exercise to understand Kotlin better).
This is the Kotlin code:
open class MyJsonArrayRequest2: JsonRequest<JSONArray>{
constructor(url: String, listener: Listener<JSONArray>, errorListener: ErrorListener):
super(Method.GET, url, null, listener, errorListener)
constructor(method: Int, url: String, jsonRequest: JSONArray, listener: Listener<JSONArray>, errorListener: ErrorListener):
super(method, url, jsonRequest.toString().replace("\\\\",""), listener, errorListener)
override fun parseNetworkResponse(response: NetworkResponse?): Response<JSONArray>{
try{
val jsonString = String(response!!.data, Charset.forName(HttpHeaderParser.parseCharset(response.headers)));
return Response.success(JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response));
}catch (e: UnsupportedEncodingException){
return Response.error(ParseError(e));
}catch (je: JSONException){
return Response.error(ParseError(je));
}
}
}
If I run my app now (it compiles without error or warning) with all requests using MyJsonArrayRequest2
instead of MyJsonArrayRequest
, I get a kotlin.KotlinNullPointerException
error.
Edit: I now understand: The response is not null when using the Java class, but it is null when using the Kotlin class. The question that arises is what is the difference between the classes that could result in such discrepancy?
I also checked the automatic translation from Java to Kotlin, but I didn't see many differences except that the automatic translation uses replaceAll()
instead of replace()
and omits some !!
and ?
. However, with replaceAll()
I got an "Unresolved reference" error and I read somewhere that Kotlin's replace()
is the same as Java's replaceAll()
.