2011-04-17 65 views
1

我需要一个建议。我试图将一个对象列表作为参数传递给使用spring-mvc 3编写的方法控制器,所有这些都使用ajax。这些对象是widget类的后代。我会告诉你,代码首先参数和继承spring-mvc通过json

Ajax调用:

function buildWidget(obj){ 
    var result = null; 
    switch(obj.className){ 
    case 'text': 
     result = { 
      x:obj.control.x 
      ,y:obj.control.y 
      ,height: obj.control.height 
      ,width: obj.control.width 
      ,text: obj.text 
     }; 
     break; 
    case 'youtube': 
     result = { 
      x:obj.control.x 
      ,y:obj.control.y 
      ,height: obj.control.height 
      ,width: obj.control.width 
      ,videos: obj.videos 
     }; 
     break; 
    } 
    return result; 
} 

var all = new Array(); 
      for(i=0;i<figures.size;i++) 
       all.push(buildWidget(figures.data[i].widget)); 
      jQuery.getJSON("pages/save.html", { widgetsList: jQuery.toJSON(all) }, function(myresult) { 
       alert('ok'); 
      }); 

服务器端

public class WidgetAdapter { 

    private int x; 
    private int y; 
    private int width; 
    private int height; 
// getters and setters 
} 

public class TextWidgetAdapter extends WidgetAdapter { 

    private String text; 

    // getters and setters 

} 

public class YoutubeWidget extends WidgetAdapter{ 

    private String videos; 

    // getters and setter 
} 

控制器(这里的问题)

@RequestMapping(value = "/pages/save",method=RequestMethod.GET) 
    public @ResponseBody String save(@RequestParam String widgetsList){ 
     Type listType = new TypeToken<List<WidgetAdapter>>() {}.getType(); 
     List<WidgetAdapter> adapters = new Gson().fromJson(widgetsList, listType); 
     for(WidgetAdapter a :adapters){ 
      System.out.println(a.getX()); 
     } 
     return new Gson().toJson(new ActionResult("msg")); 
    } 

所以,当调用方法控制器时,Gson创建一个List适配器,所有元素都是WidgetAdapter类,而不是TextWidgetAdapter或YoutubeWidget。有没有办法达到这个目标?我的意思是传递参数作为一个类的元素后代列表,并由Gson正确转换?

谢谢,我希望清楚。英语不是我的母语。

pd:我是以一种很好的方式或更好的方式来做这一切的。

回答

1

好的!我告诉你我是如何解决这个问题的。请告诉我你的意见。 我创建了一个自定义的反序列化器(在这里我创建了混凝土实例)。下面是代码:

@RequestMapping(value = "/pages/save",method=RequestMethod.GET) 
    public @ResponseBody String save(@RequestParam String widgetsList){ 
     GsonBuilder gson = new GsonBuilder(); 
     // register the custom deserializer for my WidgetAdapterClass 
     gson.registerTypeAdapter(WidgetAdapter.class, new WidgetDeserialization()); 
     Type listType = new TypeToken<List<WidgetAdapter>>() {}.getType(); 
     // create gson an deserialize object 
     List<WidgetAdapter> adapters = gson.create().fromJson(widgetsList, listType); 
     // just for testing proposes 
     for(WidgetAdapter a :adapters){ 
      System.out.println(a.getWidth()); 
     } 

     return new Gson().toJson(new ActionResult("Ok")); 
    } 

具体解串器

public class WidgetDeserialization implements JsonDeserializer<WidgetAdapter> { 

    /*** 
    * factory method for custom WidgetAdapter 
    * @param json 
    * @return WidgetAdapter 
    */ 
    private WidgetAdapter getWidget(JsonObject json){ 
     WidgetAdapter adapter = null; 
     //obtain widget class. Util for instanciate concrete class 
     String className = json.get("className").getAsString(); 
     // create concrete classes and set concrete atributes 
     if("text".equals(className)){ 
      adapter = new TextWidgetAdapter(json.get("text").getAsString()); 
     }else if("youtube".equals(className)){ 
      adapter = new YoutubeWidgetAdapter(json.get("videos").getAsString()); 
     } 
     // if adapter is created common atributes are set 
     if(adapter!=null){ 
      adapter.setHeight(json.get("height").getAsInt()); 
      adapter.setWidth(json.get("width").getAsInt()); 
      adapter.setX(json.get("x").getAsInt()); 
      adapter.setY(json.get("y").getAsInt()); 
     } 
     return adapter; 
    } 

    @Override 
    public WidgetAdapter deserialize(JsonElement element, Type arg1, 
      JsonDeserializationContext arg2) throws JsonParseException { 
     JsonObject obj = element.getAsJsonObject(); 
     return getWidget(obj); 
    } 

} 

我希望它能帮助