使用jackson,spring,stomp setup对嵌套的JSON进行反序列化

时间:2014-11-28 02:52:53

标签: json spring jstree stomp sockjs

在深入讨论这个问题之前,我使用的是一个由Spring Starter Guide gs-messaging-stomp-websocket构建的项目。根据指南我使用Stomp和SockJS。话虽如此,我还在JPA逻辑中添加了允许在从Web套接字接收更改后保留更改。我的问题是我终于能够将序列化的jstree发送到后端,但是当遇到嵌套对象时它无法反序列化它。这是来自前端的发送:

function sendNode() {
    //get rid of the leading and trailing [ ]s
    var coreTree = $("#treeStart").jstree(true).get_json('#', { 'flat': true });
    var stringifiedTree = JSON.stringify(coreTree);
    var sendableTree = stringifiedTree.substring(1, stringifiedTree.length-1);
    stompClient.send("/app/nodes", {}, sendableTree);
}

这是上面sendNode函数的输出:

{"id":"rootNode","text":"Root node 1","icon":true,"li_attr":{"id":"rootNode","class":"rootNode"},"a_attr":{"href":"#","id":"rootNode_anchor"},"state":{"loaded":true,"opened":false,"selected":false,"disabled":false},"data":{},"parent":"#","type":"default"}

目前我的Node类遵循以下约定:

@Entity
public class Node { 
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Long id_incr;

  @JsonProperty
  private String id;

  @JsonProperty
  private String text;

  @JsonProperty
  private String parent;

  @JsonProperty
  private String type;

  @JsonProperty
  private boolean icon;

  @JsonProperty
  private String[] li_attr;

  @JsonProperty
  private String[] a_attr;

  @JsonProperty 
  private String[] state;

  @JsonProperty
  private String[] data;

  private String[] nodeContents;

  protected Node(){ }
  public Node(String content){ }

  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  } 
  public String[] getNodeContents() {
    return this.nodeContents;
  } 
  public void setNodeContents(String[] nodeContents) {
    this.nodeContents = nodeContents;
  }

  public String getText() {
    return text;
  }
  public void setText(String text) {
    this.text = text;
  }
  public String getParent() {
    return parent;
  }
  public void setParent(String parent) {
    this.parent = parent;
  }
  public String getType() {
    return type;
  }
  public void setType(String type) {
    this.type = type;
  }
  public boolean isIcon() {
    return icon;
  }
  public void setIcon(boolean icon) {
    this.icon = icon;
  }
  public String[] getLi_attr() {
    return li_attr;
  }
  public void setLi_attr(String[] li_attr) {
    this.li_attr = li_attr;
  }
  public String[] getA_attr() {
    return a_attr;
  }
  public void setA_attr(String[] a_attr) {
    this.a_attr = a_attr;
  }
  public String[] getState() {
    return state;
  }
  public void setState(String[] state) {
    this.state = state;
  }
  public String[] getData() {
    return data;
  }
  public void setData(String[] data) {
    this.data = data;
  } 
}

我的控制器返回响应:

@MessageMapping("/nodes")
@SendTo("/topic/nodes")
public String[] nodes(Node node) throws Exception {
    return node.getNodeContents();
}

这是堆栈跟踪的一部分,我遇到了以下问题:

org.springframework.messaging.converter.MessageConversionException: Could not read JSON: Can not deserialize instance of java.lang.String[] out of START_OBJECT token
at [Source: [B@632d03de; line: 1, column: 50] (through reference chain: hello.Node["li_attr"])

我可能会误解某些内容,我对websockets和序列化/反序列化JSON都很陌生。提前感谢您,如果您需要更多信息或说明,请告诉我们!

2 个答案:

答案 0 :(得分:2)

我最近在一周前遇到了同样的问题我无法使用websocket sockjs stomp检索和发送对象。我建议通过实现Serializable来序列化您的节点对象。然后让我们看看将会发生什么。

@Entity
public class Node implements Serializable{ 

  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Long id_incr;

  @JsonProperty
  private String id;

  @JsonProperty
  private String text;

  @JsonProperty
  private String parent;

  @JsonProperty
  private String type;

  @JsonProperty
  private boolean icon;

  @JsonProperty
  private String[] li_attr;

  @JsonProperty
  private String[] a_attr;

  @JsonProperty 
  private String[] state;

  @JsonProperty
  private String[] data;

  private String[] nodeContents;

  protected Node(){ }
  public Node(String content){ }

  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  } 
  public String[] getNodeContents() {
    return this.nodeContents;
  } 
  public void setNodeContents(String[] nodeContents) {
    this.nodeContents = nodeContents;
  }

  public String getText() {
    return text;
  }
  public void setText(String text) {
    this.text = text;
  }
  public String getParent() {
    return parent;
  }
  public void setParent(String parent) {
    this.parent = parent;
  }
  public String getType() {
    return type;
  }
  public void setType(String type) {
    this.type = type;
  }
  public boolean isIcon() {
    return icon;
  }
  public void setIcon(boolean icon) {
    this.icon = icon;
  }
  public String[] getLi_attr() {
    return li_attr;
  }
  public void setLi_attr(String[] li_attr) {
    this.li_attr = li_attr;
  }
  public String[] getA_attr() {
    return a_attr;
  }
  public void setA_attr(String[] a_attr) {
    this.a_attr = a_attr;
  }
  public String[] getState() {
    return state;
  }
  public void setState(String[] state) {
    this.state = state;
  }
  public String[] getData() {
    return data;
  }
  public void setData(String[] data) {
    this.data = data;
  } 
}

答案 1 :(得分:0)

确保方法签名中的参数类具有空的构造函数。那对我有用。