0

这适用于所有 JSON 大脑。

假设我有一个类似的界面:

public interface Model {
  String getName();
  String getDateCreated();
  String getTimeCreated();
  String getLastUpdated();
  String getLastUpdatedTime();
}

然后假设我有一个 Item 对象:

public class Item {

  private String name;
  private Date created;
  private Date updated;

  ..setters and getters
}

然后假设我有一个模型包装器:

public class ItemModel implements Model {

  private final Item item;

  public ItemModel(Item item){
      this.item = item;
  }

  public String getName(){
      return item.getName();
  }

  public String getDateCreated(){
      Date created = item.getCreated();
      //format the date nicely and return a date string
  }

  public String getTimeCreated(){
      Date created = item.getCreated();
      //format the date nicely and return a time string
  }

  ...you get the gyst, right?
}

问题是:

  1. 如何序列化 ItemModel 以便 json 输出将反映模型接口上的 getter 名称?
  2. 具体来说,哪个库最容易做到这一点?您如何使用特定的库来实现这一点?
  3. 最后,我不想序列化包装在 ItemModel 中的 Item 对象

我希望输出是这样的:

{item : {name: '', dateCreated : '', timeCreated : '', lastUpdated : '', lastUpdatedTime : ''}

提前致谢!


我想我应该分享到目前为止我所能做的,并得到你的反馈。它几乎可以满足我的要求,但我不确定这是否正确:

这里的一位用户向我指出了 genson,我觉得它很有趣。

首先我创建了一个序列化器

公共类 ModelSerializer 实现序列化器 {

@Override
public void serialize(T target, ObjectWriter writer, Context cntxt) throws TransformationException, IOException {
    writer.beginObject();
    for (Method method : target.getClass().getMethods()) {
        String methodName = method.getName();
        if (methodName.startsWith("get")) {
            int index = "get".length();
            String valueName = Character.toLowerCase(methodName.charAt(index)) + method.getName().substring(index + 1);
            try {
                String valueString = (String) method.invoke(target, new Object[]{});
                writer.writeName(valueName).writeValue(valueString);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(ModelSerializer.class.getName()).log(Level.SEVERE, null, ex);
                throw new TransformationException(ex.getMessage());
            } catch (IllegalAccessException ex) {
                Logger.getLogger(ModelSerializer.class.getName()).log(Level.SEVERE, null, ex);
                throw new TransformationException(ex.getMessage());
            } catch (InvocationTargetException ex) {
                Logger.getLogger(ModelSerializer.class.getName()).log(Level.SEVERE, null, ex);
                throw new TransformationException(ex.getMessage());
            }
        }
    }
    writer.endObject();
}

}

接下来,我创建了 Genson 并通过了 Serializer

Genson genson = new Genson.Builder().withSerializer(new ModelSerializer(), Model.class).create();

现在,当我通过 ViewModel 时,我得到了按预期格式化的字段

模型 viewModel = new ItemModel(domainModel); 其中 domainModel 是 Item System.out.println(genson.serialize(viewModel)) 的一个实例;

4

3 回答 3

0

我会重构你的代码。首先,您想要一个 POCO 类作为您的数据载体,这将是您的项目类。然后你会想要一个存储库为你做 CRUD 操作。

public interface IItemModelRepository {
 Item getItemByName();
 Item getItemByDateCreated();
}

您将接口实现为:

public class ItemModelRepository : IItemModelRepository {

private IEnumerable<Item> _items;

public ItemModelRepository()
{
   this._items = /// Logic to load all items from database or from in memory cache
} 

public Item getItemByName(string name){
  return this._items.First(i => i.Name.Equals(name);
}

public Item getItemByDateCreated(DateTime dateCreated){
  return this._items.First(i => i.DateCreated == dateCreated);     
}

....
}

然后你可以使用这个存储库(直接在控制器中使用存储库不是一个好主意。你宁愿返回一个 ViewModel,它是一个包含视图所需属性的 POCO 类):

var item = ItemModelRespository.GetByName("enter name here");
var viewModel = new ViewModel();
var serializer = new JavaScriptSerializer();
viewModel.JsonData = serializer.Serialize(item );

在客户端,您可以使用:

<%= Model.JsonData %>

也看看这里:ASP.NET MVC: How to convert View Model into Json object

- 编辑

抱歉,错过了您使用 Java 的部分。如此处所述:

http://flax.ie/flax-engine-gwt-client-side-json-serialization-and-deserialization/

您可以将现有的项目类修改为:

public class Item implements JsonSerializable {

  private String name;
  private Date created;
  private Date updated;

 ..setters and getters

/**
* Pass this method JSON and it gives you back an object which you can
* then assign to your object via MyObject x = JsonToObject(String Json);
*
* @param JSON
* @return
*/
public static Item JsonToObject(String Json) {
    Serializer serializer = (Serializer) GWT.create(Serializer.class);
    return (Item)serializer.deSerialize(Json,"your fully qualified Item assembly name");
}

/**
* Creates a JSON string from the current object
*
* @return String of JSON
*/
public String toJson() {
    Serializer serializer = (Serializer) GWT.create(Serializer.class);
    return serializer.serialize(this);
}
}

然后在使用 IItemModelRepository 的代码中,您可以使用:

var item = ItemModelRepository.GetItemByName("name");
var jsonString = item.ToJson();

我不明白的是,当您希望 JSON 输出成为 Item 对象的序列化表示时,为什么要序列化 ​​ItemModel?

于 2012-10-04T14:51:55.027 回答
0

您可以使用Jettison之类的库手动定义自己的 JSON 映射,因此您不必使用 POJOS 和 POCO 以及包装器和其他愚蠢的东西来扭曲自己。设置映射确实不需要太多时间。

于 2012-10-04T18:45:31.373 回答
0

您可以尝试 genson 库,它提供了几种解决问题的方法http://code.google.com/p/genson/

如果所需的输出是 {name: '', dateCreated : '', timeCreated : '', lastUpdated : '', lastUpdatedTime : ''} 没有 "item :" :

public class ItemModel implements Model {    
    @JsonIgnore private final Item item; 
    ....
}

new Genson().serialize(myItemModel);

如果您想要“项目”键,您还可以像在wiki中那样实现自定义序列化器或转换器。

于 2012-10-04T15:45:02.260 回答