4

Volley で JacksonJSONRequest 実装を作成したいと考えています。ほとんどのリクエスト/レスポンスには、タイプ X のリクエスト オブジェクトとタイプ Y のレスポンス オブジェクトがあります。

Volley Request 基本クラスでは、両方を同じものとして定義しています...

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

これは私にはあまり意味がありません。リクエストとレスポンスに同じ構造を使用する多くの REST リクエストは想像できません。

ここで明らかな何かが欠けていますか?

4

2 に答える 2

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;
        }
    }
}
于 2013-07-03T07:05:24.823 に答える
0

これが役立つかどうかはわかりませんが、タイプを取り、文字列を返すジャクソンリクエストがあります。ほとんどのリクエストはヘッダーを返すだけなので、それを使用します

編集

これにはさまざまなリクエストとレスポンスのタイプがあり、非常にエレガントではありませんが、機能します

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;
}

}

于 2013-06-27T17:50:27.877 に答える