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. json 出力がモデル インターフェイスのゲッター名を反映するように ItemModel をシリアル化するにはどうすればよいですか?
  2. 具体的には、これを最も簡単に行うライブラリはどれですか? 特定のライブラリを使用してこれをどのように達成しますか?
  3. 最後に、ItemModel 内にラップされた Item オブジェクトをシリアル化したくありません

出力を次のようにしたい:

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

前もって感謝します!


これまでにやってきたことを共有し、フィードバックを得るべきだと思いました。私の要件をほぼ満たしていますが、正しい方法かどうかはわかりません。

ここのユーザーから genson を指摘されましたが、非常に興味深いと思います。

まず、シリアライザーを作成しました

public class ModelSerializer は Serializer を実装します {

@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

Jettisonのようなライブラリを使用して、独自の JSON マッピングを手動で定義できるため、POJOS や POCO、ラッパー、その他のばかげたことで自分をゆがめる必要はありません。マッピングを設定するのにそれほど時間はかかりません。

于 2012-10-04T18:45:31.373 に答える
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);     
}

....
}

次に、このリポジトリを次のように使用できます (Controller でリポジトリを直接使用することはお勧めできません。ビューに必要なプロパティを含む POCO クラスである ViewModel を返すことをお勧めします)。

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: ビュー モデルを Json オブジェクトに変換する方法

- 編集

申し訳ありませんが、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

問題を解決するいくつかの方法を提供する 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);

「item」キーが必要な場合は、wikiのようにカスタム Serializer または Converter を実装することもできます。

于 2012-10-04T15:45:02.260 に答える