2014-08-27 19 views
6

Tôi đang sử dụng chế độ ngủ đông để ánh xạ đối tượng vào cơ sở dữ liệu. Một khách hàng (ứng dụng iOS) gửi cho tôi đối tượng đặc biệt trong định dạng JSON mà tôi chuyển sang đại diện thực sự của họ bằng cách sử dụng phương pháp hữu ích sau đâyChuyển đổi JSON giữa chuỗi và byte [] với GSON

/** 
    * 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; 
    } 

Vấn đề này tuy nhiên là, rằng trong pogo tôi lưu trữ các giá trị như một byte [ ] như có thể thấy bên dưới (vì đây là những gì được lưu trữ trong cơ sở dữ liệu - một 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; 

Bây giờ tất nhiên, việc chuyển đổi không thành công vì nó không thể chuyển đổi giữa một byte [] và một string. Đây là cách tiếp cận tốt nhất ở đây để thay đổi constructor để chấp nhận một String thay vì mảng byte và sau đó tự chuyển đổi trong khi thiết lập giá trị mảng byte hoặc có cách tiếp cận tốt hơn để thực hiện điều này.

Lỗi được đưa ra như sau;

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: BEGIN_ARRAY dự kiến ​​nhưng STRING tại dòng 1 cột 96 đường $ .optionalImage

Cảm ơn

Sửa Trong thực tế, ngay cả những cách tiếp cận tôi đề nghị sẽ không hoạt động do cách thức mà GSON tạo ra các đối tượng.

+0

vấn đề là gì? Bạn không thể serialize/deserialize mảng byte bằng cách sử dụng định dạng json? Hay cái gì? – Andremoniy

+0

Tôi đang nhận một đối tượng như là json và chuyển đổi trực tiếp nó vào trong hibernate pojo của tôi. hibernate pojo hoạt động ở định dạng mảng byte. thư viện GSON chuyển đổi chuỗi thành đối tượng và dường như không chuyển đổi được byte [] – Biscuit128

+0

Lỗi trên đó là gì? – Andremoniy

Trả lời

11

Bạn có thể sử dụng adapter này để tuần tự hóa và deserialize mảng byte trong base64. Đây là nội dung.

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)); 
     } 
    } 

Ghi có cho tác giả Ori Peleg.

+1

Tôi có một HashMap - nó dường như không hoạt động đúng với bộ điều hợp toJson - Tôi nhận được các tham chiếu đối tượng Java và không phải là các giá trị base64 đích. Bất kỳ ý tưởng? –

2

Từ một số blog để tham khảo trong tương lai, trong trường hợp liên kết không khả dụng, ít nhất người dùng có thể tham khảo tại đây.

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)); 
     } 
    } 
} 
0

Bạn chỉ có thể chụp ảnh như String trong POJO, và trong phương pháp Setter chuyển đổi String để byte [] và trở về byte [] trong phương pháp 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(); 
    } 
} 
+0

Hy vọng Điều này sẽ giúp .... –

Các vấn đề liên quan