【问题标题】:How to expose a method using GSon?如何使用 GSon 公开方法?
【发布时间】:2011-09-14 12:25:31
【问题描述】:

使用 Play 框架,我通过 GSON 序列化我的模型。我指定哪些字段是公开的,哪些不公开。

这很好用,但我也想@expose 方法。当然,这也太简单了。

我该怎么做?

感谢您的帮助!

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

【问题讨论】:

    标签: java gson


    【解决方案1】:

    我遇到这个问题的最佳解决方案是制作一个专用的序列化器:

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

    并在我看来像这样使用它:

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

    但是让@Expose 为方法工作会很棒:它可以避免仅仅为了显示方法而制作序列化程序!

    【讨论】:

      【解决方案2】:

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

      这是我创建的一个库,它扩展了 Gson 以处理诸如公开方法、结果后序列化、后反序列化以及随着时间的推移我需要使用 Gson 的许多其他事情。

      这个库用于我们公司 Contactive (http://goo.gl/yueXZ3) 的生产环境中,在 Android 和 Java 后端都使用

      【讨论】:

        【解决方案3】:

        Gson's @Expose 似乎只支持字段。在此注册了一个问题:@Expose should be used with methods

        【讨论】:

          【解决方案4】:

          根据 Cyril 的回答,选择不同的选项:

          带有快捷方式的自定义序列化程序:

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

          -或- 基于注解的序列化器

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

          【讨论】:

          • 这仅在只有一个类而没有对任何其他对象的任何引用时才有效。例如,如果您有一个 List,您的方法将不起作用。
          猜你喜欢
          • 1970-01-01
          • 2017-12-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-11
          • 1970-01-01
          • 1970-01-01
          • 2012-02-20
          相关资源
          最近更新 更多