在Volley中创建Jackson解析的请​​求

时间:2013-06-27 07:56:39

标签: android android-volley

我想在Volley中创建一个JacksonJSONRequest实现。我的请求/响应与大多数一样,都有一个类型为X的请求对象,以及一个类型为Y的响应对象。

Volley Request基类将两者定义为相同......

public class JacksonRequest<T> extends Request<T>
...
protected Response<T> parseNetworkResponse(NetworkResponse response)

这对我来说没什么意义。我无法想象许多REST请求对请求和响应使用相同的结构。

我错过了一些明显的东西吗?

2 个答案:

答案 0 :(得分:4)

这是我的实施......

public class JacksonRequest<T> extends JsonRequest<T>
{
    private Class<T>    responseType;

    /**
     * Creates a new request.
     * 
     * @param method
     *            the HTTP method to use
     * @param url
     *            URL to fetch the JSON from
     * @param requestData
     *            A {@link Object} to post and convert into json as the request. Null is allowed and indicates no parameters will be posted along with request.
     * @param listener
     *            Listener to receive the JSON response
     * @param errorListener
     *            Error listener, or null to ignore errors.
     */
    public JacksonRequest(int method, String url, Object requestData, Class<T> responseType, Listener<T> listener, ErrorListener errorListener)
    {
        super(method, url, (requestData == null) ? null : Mapper.string(requestData), listener, errorListener);
        this.responseType = responseType;
    }

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response)
    {
        try
        {
            String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            return Response.success(Mapper.objectOrThrow(jsonString, responseType), HttpHeaderParser.parseCacheHeaders(response));
        }
        catch (Exception e)
        {
            return Response.error(new ParseError(e));
        }
    }
}

上面使用的Mapper类只是一个小包装类......

/**
 * Singleton wrapper class which configures the Jackson JSON parser.
 */
public final class Mapper
{
    private static ObjectMapper MAPPER;

    public static ObjectMapper get()
    {
        if (MAPPER == null)
        {
            MAPPER = new ObjectMapper();

            // This is useful for me in case I add new object properties on the server side which are not yet available on the client.   
            MAPPER.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }

        return MAPPER;
    }

    public static String string(Object data)
    {
        try
        {
            return get().writeValueAsString(data);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

    public static <T> T objectOrThrow(String data, Class<T> type) throws JsonParseException, JsonMappingException, IOException
    {
        return get().readValue(data, type);
    }

    public static <T> T object(String data, Class<T> type)
    {
        try
        {
            return objectOrThrow(data, type);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
}

答案 1 :(得分:0)

不确定这会对你有所帮助,但我有一个jackson请求,它接受一个类型并返回一个字符串,我使用它,因为我的大多数请求只返回一个标题

修改

这有不同的请求和响应类型,它不是超级优雅但它可以工作

public class JacksonJsonRequest<K, T> extends Request<T> {

private ObjectMapper mMapper = new ObjectMapper();

private static final String PROTOCOL_CHARSET = "utf-8";


private static final String PROTOCOL_CONTENT_TYPE =
        String.format("application/json; charset=%s", PROTOCOL_CHARSET);

private final Response.Listener<T> mListener;
private final K mRequestBody;
private final Class<T> mClass;
private final Map<String, String> mHeaders;




public JacksonJsonRequest(int method, String url, K requestBody,
                          Response.ErrorListener errorListener, Response.Listener<T> listener,
                          Map<String, String> headers,  Class<T> claz) {
    super(method, url, errorListener);

    mListener = listener;
    mRequestBody = requestBody;
    mHeaders = headers;
    mClass = claz;

}

@Override
protected Response<T> parseNetworkResponse(NetworkResponse networkResponse) {
    String jsonString = new String(networkResponse.data);
    try {
        T result = mMapper.readValue(jsonString, mClass);
        return Response.success(result, HttpHeaderParser.parseCacheHeaders(networkResponse));
    } catch (IOException e) {
        Log.e("jacksontest", "error parsing", e);
    }
    return null;
}

@Override
protected void deliverResponse(T t) {
    mListener.onResponse(t);
}

@Override
public String getBodyContentType() {
    return PROTOCOL_CONTENT_TYPE;
}

@Override
public byte[] getBody()  {
    try {
        return mRequestBody == null ? null : mMapper.writeValueAsBytes(mRequestBody);
    } catch (JsonProcessingException e) {
        Log.e("Jacksontest", "error parsing", e);
    }
    return null;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    return (mHeaders == null) ? super.getHeaders() : mHeaders;
}

}