Question

With the Volley libraries, I extended the Request object to implement GSON serialization. I then extended that new object for how I want to do some of my PUT requests. This is the first object for the GSON serialization:

@Override  
protected Response<t> parseNetworkResponse(NetworkResponse response) {  
    try {  
        String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); //response may be too large for string?
        t parsedGSON = mGson.fromJson(jsonString, cls);
        Response <t> returnMessage = Response.success(parsedGSON,  
                HttpHeaderParser.parseIgnoreCacheHeaders(response));
        return returnMessage;

    } catch (UnsupportedEncodingException e) { 
        e.printStackTrace();
        return Response.error(new ParseError(e));  
    } catch (JsonSyntaxException je) {
        je.printStackTrace();
        Log.e("GsonRequest", je.getMessage()!=null?je.getMessage():"JsonSyntaxError");
        return Response.error(new ParseError(je));  
    }  
}  

When my network response gets to Response <t> returnMessage = Response.success(parsedGSON, HttpHeaderParser.parseIgnoreCacheHeaders(response)); I have populated <t> objects with the correct classes I passed in completely serialized with all variables and no errors. Yet for some reason Volley jumps to } catch (JsonSyntaxException je) { and I can't reveal the contents of je with debugging breakpoints or printing logs. Also in my extended class:

 new ErrorListener() {
        @SuppressWarnings("unused")
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();

The onErrorResponse is never called (neither is my onResponse section either)

So now I have no idea why Volley is catching a JSONException, when serialization was successful, and I have no idea why Volley isn't returning the Error objects

Insight appreciated

Was it helpful?

Solution

The answer is that any Volley function you extend or override must have

    @Override
protected void deliverResponse(T response) {
    // TODO Auto-generated method stub
    mListener.onResponse(response);
}

function implemented. The Listener must be initialized in the constructor and have the onResponse method implemented.

Otherwise your network call will never return in the onResponse section.

EDIT: and your extended Request class has to also implement deliverError, along with deliverResponse

private final Listener<T> mListener;
private ErrorListener mErrorListener;

@Override
 public void deliverError(VolleyError error) {
    mErrorListener.onErrorResponse(error);
}

with ErrorListener initialized in your constructor

OTHER TIPS

I have had the same problem this morning. Probably you are not receiving a Json as response, your server is answering with a 200 OK but Volley is waiting for receiving a Json. Than, when it does not receive a Json it generates that error, which has not a HTTP code (because it is not), but is a volley internal error.

You may solve the problem by using the right object (from the volley library) for performing your requests.

If you use a JsonObjectRequest volley needs a JSONObject in the request's body and is aspecting for a JSONObject in the response object. If you use a JsonArrayRequest volley needs a JSONArray in the request and a JSONArray in the response. For each different case you need to extend the JsonRequest class for managing the response.

For JSON why don't you use own class for answer, for example:

import com.google.gson.annotations.SerializedName;

public class UserData {
@SerializedName("email")
public String userMail;
@SerializedName("number")
public String number;
@SerializedName("loginName")
public String loginName;
@SerializedName("password")
public String password;

}

and then

public Request<?> getInformation(String loginName, String password, Response.Listener<UserData> responseListener,
                                         Response.ErrorListener errorListener) {

    String url = apiURL;

    Map<String, String> authHeaders = getAuthHeaders(loginName, password);
    authHeaders.put(HEADER_PARAM_INTERFACE_KEY, DPAG_INTERFACE_KEY);
    int method = Request.Method.GET;

    GsonRequest<UserData> request = new GsonRequest<UserData>(
            method,
            url,
            UserData.class,
            authHeaders,
            responseListener,
            errorListener,
            gson);


    return mQueue.add(request);
}

plus here the onResponse and on ErrorResponse

    Application.get().getApi().getInformation(loginName, password,
            new Response.Listener<UserData>() {

                @Override
                public void onResponse(UserData data) {

                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {


                }
            }
    );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top