Java 使用 GSON 在 string 和 byte[] 之间转换 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25522309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting JSON between string and byte[] with GSON
提问by Biscuit128
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
我正在使用休眠将对象映射到数据库。客户端(iOS 应用程序)以 JSON 格式向我发送特定对象,我使用以下实用程序方法将其转换为它们的真实表示
/**
* 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)
然而,问题是,在我的 pogo 中,我将值存储为字节 [],如下所示(因为这是存储在数据库中的内容 - 一个 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.
当然,现在转换失败了,因为它不能在 byte[] 和 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
com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为 BEGIN_ARRAY,但在第 1 行第 96 列路径 $.optionalImage 处为 STRING
Thanks
谢谢
EditIn fact even the approach I suggested will not work due to the way in which GSON generates the object.
编辑事实上,由于 GSON 生成对象的方式,即使我建议的方法也不起作用。
采纳答案by Ken de Guzman
You can use this adapterto serialize and deserialize byte arrays in base64. Here's the content.
您可以使用此适配器来序列化和反序列化 base64 中的字节数组。这是内容。
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.
回答by Ankur Singhal
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));
}
}
}
回答by yogendra saxena
You can simply take the photo as String in POJO , and in Setter method convert String to byte[] and return byte[] in Getter method
您可以简单地将照片作为 POJO 中的 String ,并在 Setter 方法中将 String 转换为 byte[] 并在 Getter 方法中返回 byte[]
@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();
}
}