用GSON在字符串和字节[]之间转换JSON [英] Converting JSON between string and byte[] with GSON

查看:144
本文介绍了用GSON在字符串和字节[]之间转换JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用hibernate将对象映射到数据库。客户端(iOS应用程序)向我发送JSON格式的特定对象,并使用以下实用程序方法将其转换为其真实表示形式。

  / ** 
*将任何json字符串转换为相关的对象类型
* @param jsonString要转换的字符串
* @param classType将其转换的类
* @return创建的对象
* /
public static< T> T getObjectFromJSONString(String jsonString,Class< T> classType){

if(stringEmptyOrNull(jsonString)|| classType == null){
throw new IllegalArgumentException(无法转换null或空的json反对);


try(Reader reader = new StringReader(jsonString)){
Gson gson = new GsonBuilder()。create();
返回gson.fromJson(reader,classType);
} catch(IOException e){
Logger.error(无法在将对象作为字符串时关闭阅读器,e);
}
返回null;





$ p

然而,问题是,在我的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)
保护字符串homeContactNumber;

@Column(name =mobilephonenumber)
保护字符串mobileContactNumber;

@Column(name =photo)
private byte [] optionalImage;

@Column(name =address)
私有字符串地址;

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

在这里最好的方法是将构造函数改为接受一个String而不是一个字节数组,然后在设置字节数组值时自己进行转换,或者是否存在更好的方法来做到这一点。

抛出的错误如下;


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


感谢

编辑实际上,即使我提出的方法也不会工作,因为GSON生成对象。

解决方案

您可以使用适配器来对base64中的字节数组进行序列化和反序列化。
这里是内容。

  public static final Gson customGson = new GsonBuilder()。registerTypeHierarchyAdapter(byte []。class ,
new ByteArrayToBase64TypeAdapter())。create();

//使用Android的base64库。这可以被任何base64库替换。
private static class ByteArrayToBase64TypeAdapter实现JsonSerializer< byte []>,JsonDeserializer< byte []> {
public byte [] deserialize(JsonElement json,Type typeOfT,JsonDeserializationContext context)throws JsonParseException {
返回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

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.

解决方案

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.

这篇关于用GSON在字符串和字节[]之间转换JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆