2014-08-27 14 views
6

Sto utilizzando la modalità di sospensione per mappare gli oggetti nel database. Un client (un app iOS) mi manda particolari oggetti in formato JSON che ho convertire in loro vera rappresentazione utilizzando il seguente metodo di utilitàConversione di JSON tra stringa e byte [] con 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; 
    } 

La questione però è, che nel mio pogo devo conservare il valore come un byte [ ] come si può vedere qui di seguito (in quanto questo è ciò che è memorizzato nel database - un 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; 

Ora, naturalmente, la conversione non riesce, perché non in grado di convertire tra un byte [] e una stringa.

È l'approccio migliore qui per modificare il costruttore in modo che accetti una stringa anziché una matrice di byte e quindi esegua la conversione mentre si imposta il valore dell'array di byte o esiste un approccio migliore per farlo.

L'errore generato è il seguente;

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: BEGIN_ARRAY previsto, ma era STRING alla linea 1 della colonna 96 percorso $ .optionalImage

Grazie

Modifica In effetti, anche l'approccio che ho suggerito non funzionerà a causa del modo in cui GSON genera l'oggetto.

+0

Qual è il problema? Non puoi serializzare/deserializzare l'array di byte usando il formato json? O cosa? – Andremoniy

+0

Sto ricevendo un oggetto come json e lo converto direttamente nel mio pojo di sospensione. il pojo ibernato funziona in formato array di byte. la libreria GSON converte la stringa in oggetto e sembra che non riesca a convertire il byte [] – Biscuit128

+0

Qual è l'errore in caso di errore? – Andremoniy

risposta

11

È possibile utilizzare questo adapter per serializzare e deserializzare gli array di byte in base64. Ecco il contenuto.

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

Credito all'autore Ori Peleg.

+1

Ho un HashMap - non sembra funzionare correttamente con l'adattatore toJson - Ricevo riferimenti a oggetti Java e non i valori base64 di destinazione. Qualche idea? –

2

Da alcuni blog per riferimento futuro, nel caso il collegamento non sia disponibile, gli utenti di atleast possono fare riferimento qui.

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

si può semplicemente prendere la foto come stringa in POJO e nel Setter metodo di convertire la stringa di byte [] e tornare byte [] nel metodo 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

Hope Questo aiuterà .... –

Problemi correlati