2011-09-14 10 views
19

Al usar Play Framework, serializo mis modelos a través de GSON. Especifico qué campos están expuestos y cuáles no.¿Cómo exponer un método usando GSon?

Esto funciona muy bien pero también me gustaría exponer el método. Por supuesto, esto es muy simple.

¿Cómo puedo hacerlo?

Gracias por su ayuda!

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() { 
     // ... 
    } 
} 

Respuesta

19

La mejor solución que encontré con este problema era hacer un serializador dedicado:

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

} 

Y para utilizar de esta manera en mi opinión:

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

Pero tener @Expose de trabajo de un método sería genial: ¡evitaría crear un serializador solo por mostrar los métodos!

11

Salida Gson en el fuego: https://github.com/julman99/gson-fire

Es una biblioteca que hizo que se extiende Gson para manejar casos como la exposición de método, los resultados posteriores a la serialización, Post-deserialización y muchas otras cosas que he necesitado más tiempo con Gson.

Esta biblioteca se utiliza en la producción en nuestra empresa Contactive (http://goo.gl/yueXZ3), tanto en Android y el back-end de Java

2

par de opciones diferentes en función de la respuesta de Cyril:

serializador personalizado con un acceso directo:

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

} 

-O- anotación serializador basado

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

Esto sólo funciona si sólo hay una clase sin ninguna referencia a ningún otro objeto. Si tiene, por ejemplo, una lista , su método no funcionaría. – 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} 
Cuestiones relacionadas