Na minha situação, eu tenho um "modelo", composto por vários parâmetros String, com exceção de um: é uma matriz de bytes byte[]
. Algum trecho de código:
String response = args[0].toString();
Gson gson = new Gson();
BaseModel responseModel = gson.fromJson(response, BaseModel.class);
A última linha acima é quando o
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column
é acionado. Pesquisando no SO, percebi que precisava ter alguma forma de Adapter
converter meu BaseModel
JsonObject para lá e para cá. A mistura de String
e byte[]
em um modelo complica as coisas. Aparentemente, Gson
realmente não gosto da situação.
Acabo fazendo um Adapter
para garantir que byte[]
seja convertido em Base64
formato. Aqui está a minha Adapter
turma:
public class ByteArrayToBase64Adapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {
@Override
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return Base64.decode(json.getAsString(), Base64.NO_WRAP);
}
@Override
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(Base64.encodeToString(src, Base64.NO_WRAP));
}
}
Para converter JSONObject em modelo, usei o seguinte:
Gson customGson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64Adapter()).create();
BaseModel responseModel = customGson.fromJson(response, BaseModel.class);
Da mesma forma, para converter o modelo em JSONObject, usei o seguinte:
Gson customGson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64Adapter()).create();
String responseJSon = customGson.toJson(response);
O que o código está fazendo é basicamente enviar a classe pretendida class/object
(nesse caso, byte[]
classe) para o momento em Adapter
que for encontrada durante a conversão em / para JSONObject.