java - Conversión de JSON entre cadena y byte[] con GSON
hibernate bytearray (3)
Puede usar este adaptador para serializar y deserializar matrices de bytes en base64. Aquí está el contenido.
public static final Gson customGson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class,
new ByteArrayToBase64TypeAdapter()).create();
// Using Android''s base64 libraries. This can be replaced with any base64 library.
private static class ByteArrayToBase64TypeAdapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return Base64.decode(json.getAsString(), Base64.NO_WRAP);
}
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(Base64.encodeToString(src, Base64.NO_WRAP));
}
}
Gracias al autor Ori Peleg .
Estoy usando Hibernate para mapear objetos a la base de datos. Un cliente (una aplicación de iOS) me envía objetos particulares en formato JSON que convierto a su verdadera representación utilizando el siguiente método de utilidad
/**
* Convert any json string to a relevant object type
* @param jsonString the string to convert
* @param classType the class to convert it too
* @return the Object created
*/
public static <T> T getObjectFromJSONString(String jsonString, Class<T> classType) {
if(stringEmptyOrNull(jsonString) || classType == null){
throw new IllegalArgumentException("Cannot convert null or empty json to object");
}
try(Reader reader = new StringReader(jsonString)){
Gson gson = new GsonBuilder().create();
return gson.fromJson(reader, classType);
} catch (IOException e) {
Logger.error("Unable to close the reader when getting object as string", e);
}
return null;
}
Sin embargo, el problema es que en mi pogo almaceno el valor como un byte [] como se puede ver abajo (ya que esto es lo que está almacenado en la base de datos - un blob)
@Entity
@Table(name = "PersonalCard")
public class PersonalCard implements Card{
@Id @GeneratedValue
@Column(name = "id")
private int id;
@OneToOne
@JoinColumn(name="userid")
private int userid;
@Column(name = "homephonenumber")
protected String homeContactNumber;
@Column(name = "mobilephonenumber")
protected String mobileContactNumber;
@Column(name = "photo")
private byte[] optionalImage;
@Column(name = "address")
private String address;
Ahora, por supuesto, la conversión falla porque no puede convertir entre un byte [] y una cadena.
Es el mejor enfoque aquí para cambiar el constructor para aceptar una cadena en lugar de una matriz de bytes y luego hacer la conversión yo mismo mientras se establece el valor de matriz de bytes o hay un mejor enfoque para hacer esto.
El error arrojado es el siguiente;
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: se esperaba BEGIN_ARRAY pero estaba STRING en la línea 1 columna 96 ruta $ .optionalImage
Gracias
Editar De hecho, incluso el enfoque que sugerí no funcionará debido a la forma en que GSON genera el objeto.
De algún blog para referencia futura, en caso de que el enlace no esté disponible, al menos los usuarios pueden consultar aquí.
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.util.Date;
public class GsonHelper {
public static final Gson customGson = new GsonBuilder()
.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return new Date(json.getAsLong());
}
})
.registerTypeHierarchyAdapter(byte[].class,
new ByteArrayToBase64TypeAdapter()).create();
// Using Android''s base64 libraries. This can be replaced with any base64 library.
private static class ByteArrayToBase64TypeAdapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return Base64.decode(json.getAsString(), Base64.NO_WRAP);
}
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(Base64.encodeToString(src, Base64.NO_WRAP));
}
}
}
Simplemente puede tomar la foto como Cadena en POJO, y en el método Setter convertir Cadena en byte [] y devolver byte [] en el método Getter
@Entity
@Table(name = "PersonalCard")
public class PersonalCard implements Card
{
@Id @GeneratedValue
@Column(name = "id")
private int id;
@OneToOne
@JoinColumn(name="userid")
private int userid;
@Column(name = "homephonenumber")
protected String homeContactNumber;
@Column(name = "mobilephonenumber")
protected String mobileContactNumber;
@Column(name = "photo")
private byte[] optionalImage;
@Column(name = "address")
private String address;
@Column
byte[] optionalImage;
public byte[] getOptionalImage()
{
return optionalImage;
}
public void setOptionalImage(String s)
{
this.optionalImage= s.getBytes();
}
}