Spring websocket @messagemapping serialization problem java.lang.ClassCastException: java.util.LinkedHashMap cannot be undone

I am writing a spring websocket application using StompJS on the client side.

On the client side, I am going to send a list of objects and on the server side, when it is mapped to a java object, it converts itself to LinkedHashMap

My client code

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

Listids looks like

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

List Id object looks like

 public class ListId { private String path; private Long id; //getters and setters... } 

The controller is as follows

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

So, I get java.lang.ClassCastException: java.util.LinkedHashMap cannot be attributed to com.blah.ListId

However, when I do the same with a regular spring controller with RestMapping, it works fine, is there anything with MessageMapping springs annotations that map objects to java differently than the traditional way I'm not sure why not listing ListID

+5
source share
2 answers

I changed it from a list to an array and it works! Here is what i did

 @MessageMapping("/call" ) @SendTo("/topic/showResult") public RetObj process(ListId[] listIds) { if (!listIds.isEmpty()) { for(ListId listId: listIds) { } } 

Thanks to this question, ClassCastException: RestTemplate returns List <LinkedHashMap> instead of <MymodelClass>

+1
source

I know that this question has already been answered, but here is another solution.

To get Jackson to convert your JSON array to a list, you have to wrap it in another object and serialize / deserialize this object.

So, you will need to send the next JSON to the server

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

The list is wrapped in another object.

Below is a shell class

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

and the message method will become

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

Test code

 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\":\"/a/b/c.txt\",\"id\":12},{\"path\":\"/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 
+1
source

Source: https://habr.com/ru/post/1237950/


All Articles