【问题标题】:Play! framework renderJson not exposing particular fields玩!框架 renderJson 不公开特定字段
【发布时间】:2011-09-09 11:58:02
【问题描述】:

我试图通过 renderJson() 在我的模型中公开一个动态(瞬态)字段,但它不起作用。这是一个例子:

@Entity
public class Room extends Model {

  public String name;
  public String code;
  @Transient
  public List<Booking> bookings;

  @Transient
  @Expose
  public String resource_uri;

  public Room(String name, String code) {
    this.name = name;
    this.code = code;
  }

  public List<Booking> getBookings() {
    return Booking.find("byRoom", this).fetch();
  }

  public String getResource_uri(){
    return "/api/room/" + this.id; //the uri is evaluated dynamically.
  }

调用 renderJson(Room.findById(2)) 将其呈现为响应:

{"name":"Room B","code":"R-B","id":2}

缺少 resource_uri 字段。 @Expose 注释似乎什么都不做。而且我无法查看renderJson的声明,因为框架通过注释生成所有代码。

【问题讨论】:

    标签: java json annotations playframework gson


    【解决方案1】:

    玩!使用 Gson。它不会序列化瞬态字段。

    看看https://sites.google.com/site/gson/gson-user-guide#TOC-Object-Examples

    我喜欢 Gson,因为它带有 Play!盒子外面。 您可以构建自己的适配器,例如:

    public class RoomAdapter implements JsonDeserializer<Room>, JsonSerializer<Room> {
        public Room deserialize(JsonElement json, Type type, JsonDeserializationContext context){
            // Parse the Json to build a Room
        }
    
        public JsonElement serialize(Room room, Type type, JsonSerializationContext context){
            // Insert magic here!!
        }
    }
    

    注册序列化器:

    Gson gson = new GsonBuilder().registerTypeAdapter(
                Room.class, new RoomAdapter()).create();
    

    并使用 gson 指定要序列化的类:

    String jsonRoom = gson.toJson(aRoom, Room.class);
    Room aRoom = gson.fromJson(jsonRoom, Room.class);
    

    【讨论】:

    • 有没有办法让它序列化瞬态字段? resource_uri 并不是我想要持久保存到数据库的东西,因为它只是用于 REST 接口的元数据。
    • 经过进一步挖掘,我发现 Gson 无法序列化属性。完全没有。显然,这是因为它使用反射来查找字段。我可以查看哪些具有此功能的替代方案? FlexJSON?
    • 你可以用 Gson 来做,我已经在我的回答中发布了一个自定义适配器的例子。
    【解决方案2】:

    您的字段声明似乎存在差异,您有

    @Transient
    @Expose
    public String resource_uri;
    

    你也有

    public String getResource_uri(){
       return "/api/room/" + this.id; //the uri is evaluated dynamically.
    }
    

    这表明您的 resource_uri 字段永远为空?

    【讨论】:

    • 但它不是空的,当我 System.out.println(u.resource_uri); 时它会显示在终端中。它显示为“/api/room/2”,但我可以看到我的评论如何令人困惑,“uri 是动态评估的”,而不是直接作为持久性 ORM 字段检索。
    【解决方案3】:

    Play framework 2.0 使用 jackson 制作 json 字符串。在您不想公开的字段上使用 @JsonIgnore 注释

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-11
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 2022-08-03
      • 2016-06-28
      • 2021-12-16
      • 1970-01-01
      相关资源
      最近更新 更多