2011-09-14 14 views
19

Utilizzando Play Framework, serializzo i miei modelli tramite GSON. Specifico quali campi sono esposti e quali no.Come esporre un metodo usando GSon?

Questo funziona benissimo, ma mi piacerebbe anche il metodo @expose. Certo, questo è troppo semplice.

Come posso farlo?

Grazie per il vostro aiuto!

public class Account extends Model { 
    @Expose 
    public String username; 

    @Expose 
    public String email; 

    public String password; 

    @Expose // Of course, this don't work 
    public String getEncodedPassword() { 
     // ... 
    } 
} 

risposta

19

La soluzione migliore mi è venuto con questo problema è stato quello di fare un serializzatore dedicato:

public class AccountSerializer implements JsonSerializer<Account> { 

    @Override 
    public JsonElement serialize(Account account, Type type, JsonSerializationContext context) { 
     JsonObject root = new JsonObject(); 
     root.addProperty("id", account.id); 
     root.addProperty("email", account.email); 
     root.addProperty("encodedPassword", account.getEncodedPassword()); 

     return root; 
    } 

} 

e di utilizzarlo in questo modo, a mio avviso:

GsonBuilder gson = new GsonBuilder(); 
gson.registerTypeAdapter(Account.class, new AccountSerializer()); 
Gson parser = gson.create(); 
renderJSON(parser.toJson(json)); 

Ma avendo @Expose lavorare per un metodo sarebbe fantastico: eviterebbe di creare un serializzatore solo per mostrare i metodi!

11

Partenza GSON on Fire: https://github.com/julman99/gson-fire

E 'una libreria ho fatto che si estende GSON per gestire casi come metodo di esporre, risultati post-serializzazione, Post-deserializzazione e molte altre cose che ho bisogno di passare del tempo con GSON.

Questa libreria è utilizzato nella produzione nella nostra azienda Contactive (http://goo.gl/yueXZ3), sia su Android e il backend Java

2

paio di opzioni diverse in base alla risposta di Cirillo:

serializzatore personalizzata con una scorciatoia:

public static class Sample 
{ 
    String firstName = "John"; 
    String lastName = "Doe"; 

    public String getFullName() 
    { 
     return firstName + " " + lastName; 
    } 
} 

public static class SampleSerializer implements JsonSerializer<Sample> 
{ 
    public JsonElement serialize(Sample src, Type typeOfSrc, JsonSerializationContext context) 
    { 
     JsonObject tree = (JsonObject)new Gson().toJsonTree(src); 
     tree.addProperty("fullName", src.getFullName()); 
     return tree; 
    } 
} 

public static void main(String[] args) throws Exception 
{ 
    GsonBuilder gson = new GsonBuilder(); 
    gson.registerTypeAdapter(Sample.class, new SampleSerializer()); 
    Gson parser = gson.create(); 
    System.out.println(parser.toJson(new Sample())); 

} 

OPPURE annotazione serializzatore basato

public static class Sample 
{ 
    String firstName = "John"; 
    String lastName = "Doe"; 

    @ExposeMethod 
    public String getFullName() 
    { 
     return firstName + " " + lastName; 
    } 
} 

public static class MethodSerializer implements JsonSerializer<Object> 
{ 
    public JsonElement serialize(Object src, Type typeOfSrc, JsonSerializationContext context) 
    { 
     Gson gson = new Gson(); 
     JsonObject tree = (JsonObject)gson.toJsonTree(src); 

     try 
     {    
      PropertyDescriptor[] properties = Introspector.getBeanInfo(src.getClass()).getPropertyDescriptors(); 
      for (PropertyDescriptor property : properties) 
      { 
       if (property.getReadMethod().getAnnotation(ExposeMethod.class) != null) 
       { 
        Object result = property.getReadMethod().invoke(src, (Object[])null); 
        tree.add(property.getName(), gson.toJsonTree(result)); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      ex.printStackTrace(); 
     } 

     return tree; 
    } 
} 

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) //can use in method only. 
public static @interface ExposeMethod {} 

public static void main(String[] args) throws Exception 
{ 
    GsonBuilder gson = new GsonBuilder(); 
    gson.registerTypeAdapter(Sample.class, new MethodSerializer()); 
    Gson parser = gson.create(); 
    System.out.println(parser.toJson(new Sample())); 

} 
+0

Questo funziona solo se v'è una sola classe, senza alcun riferimento a qualsiasi altro oggetto. Se si dispone ad esempio di un elenco , il metodo non funzionerebbe. – Martin

0

http://camelcode.org/tutorial/[email protected]

package org.camelcode; 

import com.google.gson.annotations.Expose; 

public class Book { 

    @Expose 
    private String author; 
    @Expose 
    private String title; 
    private Integer year; 
    private Double price; 

    public Book() { 
     this("camelcode.org", "Exclude properties with Gson", 1989, 49.55); 
    } 

    public Book(String author, String title, Integer year, Double price) { 
     this.author = author; 
     this.title = title; 
     this.year = year; 
     this.price = price; 
    } 
} 

package org.camelcode; 

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 

public class WriteGson { 

    public static void main(String[] args) { 

     Gson gson = new GsonBuilder() 
       .excludeFieldsWithoutExposeAnnotation() 
       .create(); 

     String json = gson.toJson(new Book()); 
     System.out.println(json); 

     Gson gsonNonExcluded = new Gson(); 
     String jsonNonExcluded = gsonNonExcluded.toJson(new Book()); 
     System.out.println(jsonNonExcluded); 
    } 
} 

{"author":"camelcode.org","title":"Exclude properties with Gson"} 
{"author":"camelcode.org","title":"Exclude properties with Gson","year":1989,"price":49.55} 
Problemi correlati