使用GSON在字符串和byte []之间转换JSON

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用GSON在字符串和byte []之间转换JSON相关的知识,希望对你有一定的参考价值。

我正在使用hibernate将对象映射到数据库。客户端(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;
    }

然而问题是,在我的pogo中,我将值存储为byte [],如下所示(因为这是存储在数据库中的内容 - 一个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;

当然,转换失败是因为它无法在byte []和String之间进行转换。

这里最好的方法是将构造函数更改为接受String而不是字节数组,然后在设置字节数组值时自己进行转换,或者有更好的方法来执行此操作。

抛出的错误如下;

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_ARRAY,但在第1行第96列为STRING路径$ .optionalImage

谢谢

编辑事实上,由于GSON生成对象的方式,即使我建议的方法也行不通。

答案

您可以使用此adapter在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));
        }
    }

感谢作者Ori Peleg

另一答案

从某些博客中获取以供参考,如果链接不可用,至少用户可以参考这里。

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));
        }
    }
}
另一答案

您可以简单地将照片作为字符串在POJO中,并在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();
    }
}

以上是关于使用GSON在字符串和byte []之间转换JSON的主要内容,如果未能解决你的问题,请参考以下文章

使用Google的Gson实现对象和json字符串之间的转换

jsonObject和JsonArray转化String

jackson使用入门

JSON转换为GSON和POJO类

Gson关于抽象类的序列化与反序列化

java中字节数组byte[]和字符(字符串)之间的转换