2013-11-07 1 views
3

Используя Flexjson, я пытаюсь сериализовать объект («Полезная нагрузка»), который содержит список. Каждый MyBean имеет поле «items», которое представляет собой Map>. Когда я сериализую этот объект Payload, поле карты («элементы») пуст.Flexjson - как сериализовать сложную иерархию, включая карту

public class Payload { 

private List<MyBean> myBeans = new ArrayList<MyBean>(); 

//the JSON returned has blank values for myBeans.values.items 
public String toJson() { 
     return new JSONSerializer() 
      .exclude("*.class") 
      .include("myBeans") 
      .serialize(this); 
} 

}

Однако, когда я сериализации MyBean объект напрямую, он отлично работает.

public class MyBean { 

private Map<String, List<SomeBean>> items = new HashMap<String, List<SomeBean>>(); 

//this works 
public String toJson() { 
     return new JSONSerializer() 
      .exclude("*.class") 
      .deepSerialize(this); 
} 

}

Любые предложения?

+0

Я на самом деле есть решение и разместить его, когда StackOverflow позволяет мне. Я создал этот вопрос, чтобы попытаться избавить других от боли, с которой я прошел :) – davedonohue

+0

Хорошая работа! +1 в Q +1 в A – rpax

ответ

2

Пробуя кучу вещей, я нашел это решение. Я создал собственный трансформатор для карт. Просто скопировал Flexjson MapTransformer и закомментировал условие IF. Новый код ниже

public class Payload { 

    private List<MyBean> myBeans = new ArrayList<MyBean>(); 

    //the JSON returned has blank values for myBeans.values.items 
    public String toJson() { 
      return new JSONSerializer() 
       .exclude("*.class") 
       .include("myBeans") 
       .transform(new SOMapTransformer(), Map.class) 
       .serialize(this); 
    } 
} 


public class MyBean { 

    private Map<String, List<SomeBean>> items = new HashMap<String, List<SomeBean>>(); 

    //this works 
    public String toJson() { 
      return new JSONSerializer() 
       .exclude("*.class") 
      .transform(new SOMapTransformer(), "items") 
       .deepSerialize(this); 
    } 
} 

Вот обычай SOMapTransformer:

import com.mycompany.mypackage.SomeBean; 

import flexjson.JSONContext; 
import flexjson.Path; 
import flexjson.TypeContext; 
import flexjson.transformer.AbstractTransformer; 
import flexjson.transformer.TransformerWrapper; 

    public class SOMapTransformer extends AbstractTransformer { 

     public void transform(Object object) { 
      JSONContext context = getContext(); 
      Path path = context.getPath(); 
      Map<String, List<SomeBean>> value = (Map<String, List<SomeBean>>) object; 

      TypeContext typeContext = getContext().writeOpenObject(); 
      for (Object key : value.keySet()) { 
       path.enqueue((String) key); 

       //DPD 2013-11-04: This bloody line of code cost me 12 hours. Comment it out! 
//    if (context.isIncluded((String) key, value.get(key))) { 

        TransformerWrapper transformer = (TransformerWrapper)context.getTransformer(value.get(key)); 

        if(!transformer.isInline()) { 
         if (!typeContext.isFirst()) getContext().writeComma(); 
         typeContext.setFirst(false); 
         getContext().writeName(key.toString()); 
        } 

        typeContext.setPropertyName(key.toString()); 

        transformer.transform(value.get(key)); 

//    } 

       path.pop(); 

      } 
      getContext().writeCloseObject(); 
     } 
+1

Он никогда не перестает удивлять меня обручами, которые пользователь Java JSON перескакивает, чтобы сделать вещи, которые просто невероятно просты, если вы просто используете карты и списки и забываете о том, как отображать материал на другие объекты. –

 Смежные вопросы

  • Нет связанных вопросов^_^