2015-12-11 47 views
5

Sto scrivendo un'applicazione di websocket a molla con StompJS sul lato client.Websocket di primavera @messagemapping problema di serializzazione java.lang.ClassCastException: java.util.LinkedHashMap non può essere lanciato

Sul lato client che sto l'intenzione di inviare un elenco di oggetti e sul lato server quando è mappatura in oggetto Java, si trasforma in un LinkedHashMap

Il mio codice lato client è

function stomball() { 
     stompClient.send("/brkr/call", {}, JSON.stringify(listIds)); 
    } 

Listids sembra

[{ 
    "path": "https://stackoverflow.com/a/b/c.txt", 
    "id": 12 
}, { 
    "path": "https://stackoverflow.com/a/b/c/d.txt", 
    "id": 13 
}] 

Lista Id oggetto assomiglia

public class ListId { 

    private String path; 

    private Long id; 

    //getters and setters... 
} 

Il controller si presenta così

@MessageMapping("/call") 
@SendTo("/topic/showResult") 
public RetObj process(List<ListId> listIds) { 
    if (!listIds.isEmpty()) { 
     for(ListId listId: listIds) { 

     } 
} 

così ottengo un java.lang.ClassCastException: java.util.LinkedHashMap non può essere lanciato a com.blah.ListId

Tuttavia quando faccio il lo stesso con il normale controller Spring con RestMapping funziona, c'è qualcosa con l'annotazione di MessageMapping che mappa gli oggetti su java in modo diverso rispetto al modo tradizionale Non sono sicuro del perché non sto trasmettendo a ListID

+1

Puoi mostrarci dove è configurato il tuo objectmapper? – Andreas

+0

Il tuo ListId è serializzabile? – Andreas

+0

L'objectmapper è configurato come Il ListId non è serializzabile, ho aggiunto la serializzazione e sto girando nello stesso problema .. – user1707141

risposta

1

So che questa domanda è già stata risolta ma qui è un'altra soluzione.

Per fare in modo che Jackson converta l'array JSON in elenco, è necessario avvolgerlo in un altro oggetto e serializzarlo/deserializzare.

Quindi dovrete inviare in seguito al server JSON

{ 
    list: [ 
     { 
      "path": "https://stackoverflow.com/a/b/c.txt", 
      "id": 12 
     }, { 
      "path": "https://stackoverflow.com/a/b/c/d.txt", 
      "id": 13 
     } 
    ] 
} 

List è avvolto in un altro oggetto.

Segue la classe wrapper

class ServiceRequest { 
    private List<ListId> list; 

    public List<ListId> getList() { 
     if (list == null) { 
      list = new ArrayList<ListId>(); 
     } 
     return list; 
    } 
} 

e il metodo messaggio diventerà

@MessageMapping("/call") 
@SendTo("/topic/showResult") 
public RetObj process(ServiceRequest request) { 
    List<ListId> listIds = request.getList(); 
    if (!listIds.isEmpty()) { 
     for(ListId listId: listIds) { 

     } 
    } 
} 

codice di prova

import java.util.ArrayList; 
import java.util.List; 
import org.codehaus.jackson.map.ObjectMapper; 

public class TestJackson { 
    public static void main(String[] args) throws Exception { 
     System.out.println("Started"); 
     String json = "{\"list\":[{\"path\":\"https://stackoverflow.com/a/b/c.txt\",\"id\":12},{\"path\":\"https://stackoverflow.com/a/b/c/d.txt\",\"id\":13}]}"; 

     ObjectMapper mapper = new ObjectMapper(); 

     ServiceRequest response = mapper.readValue(json.getBytes("UTF-8"), ServiceRequest.class); 

     for(ListId listId : response.getList()) { 
      System.out.println(listId.getId() + " : " + listId.getPath()); 
     } 
    } 

    public static class ServiceRequest { 
     private List<ListId> list; 

     public List<ListId> getList() { 
      if (list == null) { 
       list = new ArrayList<ListId>(); 
      } 
      return list; 
     } 
    } 

    public static class ListId { 
     private String path; 
     private String id; 

     public String getPath() { 
      return path; 
     } 
     public void setPath(String path) { 
      this.path = path; 
     } 
     public String getId() { 
      return id; 
     } 
     public void setId(String id) { 
      this.id = id; 
     } 
    } 

} 

Test Output

Started 
12 : /a/b/c.txt 
13 : /a/b/c/d.txt