2011-09-14 16 views
19

Korzystając z Play Framework, serializuję moje modele za pośrednictwem GSON. Określam, które pola są eksponowane, a które nie.Jak odsłonić metodę za pomocą GSon?

Działa to znakomicie, ale chciałbym także zastosować metodę @expose. Oczywiście jest to zbyt proste.

Jak mogę to zrobić?

Dzięki za pomoc!

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

Odpowiedz

19

Najlepszym rozwiązaniem przyjechałem z tego problemu było stworzenie dedykowanego serializatora:

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

} 

I używać go tak jak to moim zdaniem:

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

Ale mając @Expose pracującego dla metody Byłoby świetnie: unikałoby serializowania do pokazywania metod!

11

Wyjazd Gson on Fire: https://github.com/julman99/gson-fire

Jest to biblioteka zrobiłem który rozciąga Gson obsługiwać przypadki jak odsłaniając metody, wyniki Post-serializacji, post-deserializacji i wiele innych rzeczy, które mam potrzebne w miarę upływu czasu z Gson.

Biblioteka ta jest wykorzystywana w produkcji w naszej firmie Contactive (http://goo.gl/yueXZ3), zarówno Android i Java Backend

2

kilka różnych opcji opartych na Cyryla odpowiedź:

niestandardowe serializatora ze skrótu:

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

} 

LUB Adnotacja serializer oparty

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

Działa to tylko jeśli jest tylko jedna klasa, bez odniesienia do jakiegokolwiek innego obiektu. Jeśli masz na przykład listę , twoja metoda nie zadziałałaby. – 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} 
Powiązane problemy