问题
I am using hibernate to map objects to the database. A client (an iOS app) sends me particular objects in JSON format which I convert to their true representation using the following utility method
/**
* 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;
}
The issue however is, that in my pogo I store the value as a byte[] as can be seen below (as this is what is stored in the database - a 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;
Now of course, the conversion fails because it can't convert between a byte[] and a String.
Is the best approach here to change the constructor to accept a String instead of a byte array and then do the conversion myself whilst setting the byte array value or is there a better approach to doing this.
The error thrown is as follows;
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 96 path $.optionalImage
Thanks
Edit In fact even the approach I suggested will not work due to the way in which GSON generates the object.
回答1:
You can use this adapter to serialize and deserialize byte arrays in base64. Here's the content.
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));
}
}
Credit to the author Ori Peleg.
回答2:
From some blog for future reference, incase the link is not available, atleast users can refer here.
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));
}
}
}
回答3:
You can simply take the photo as String in POJO , and in Setter method convert String to byte[] and return byte[] in Getter method
@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();
}
}
来源:https://stackoverflow.com/questions/25522309/converting-json-between-string-and-byte-with-gson