Spring websocket @messagemapping 反序列化问题java.lang.ClassCastException: java.util.LinkedHashMap 无法转换
Spring websocket @messagemapping de-serialization issue java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast
我正在编写一个 spring 在客户端使用 StompJS 的 websocket 应用程序。
在客户端,我打算发送对象列表,在服务器端,当它映射到 java 对象时,它会将自己转换为 LinkedHashMap
我的客户端代码是
function stomball() {
stompClient.send("/brkr/call", {}, JSON.stringify(listIds));
}
Listids 看起来像
[{
"path": "/a/b/c.txt",
"id": 12
}, {
"path": "/a/b/c/d.txt",
"id": 13
}]
List Id 对象看起来像
public class ListId {
private String path;
private Long id;
//getters and setters...
}
控制器看起来像这样
@MessageMapping("/call" )
@SendTo("/topic/showResult")
public RetObj process(List<ListId> listIds) {
if (!listIds.isEmpty()) {
for(ListId listId: listIds) {
}
}
所以我得到一个 java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.blah.ListId
然而,当我对带有 RestMapping 的普通 Spring 控制器执行相同操作时,它工作正常,是否有任何带有 springs MessageMapping 注释的东西将对象映射到 java 不同于传统方法
我不确定为什么不转换为 ListID
我将它从列表更改为数组,并且有效!这是我做的
@MessageMapping("/call" )
@SendTo("/topic/showResult")
public RetObj process(ListId[] listIds) {
if (!listIds.isEmpty()) {
for(ListId listId: listIds) {
}
}
感谢这个问题ClassCastException: RestTemplate returning List<LinkedHashMap> instead of List<MymodelClass>
我知道这个问题已经得到解答,但这里有另一个解决方案。
要让 Jackson 将您的 JSON 数组转换为列表,您必须将其包装在另一个对象中,然后 serialize/deserialize 该对象。
因此您必须将以下 JSON 发送到服务器
{
list: [
{
"path": "/a/b/c.txt",
"id": 12
}, {
"path": "/a/b/c/d.txt",
"id": 13
}
]
}
列表被包装到另一个对象中。
下面是包装器class
class ServiceRequest {
private List<ListId> list;
public List<ListId> getList() {
if (list == null) {
list = new ArrayList<ListId>();
}
return list;
}
}
消息方法将变为
@MessageMapping("/call" )
@SendTo("/topic/showResult")
public RetObj process(ServiceRequest request) {
List<ListId> listIds = request.getList();
if (!listIds.isEmpty()) {
for(ListId listId: listIds) {
}
}
}
测试代码
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;
}
}
}
测试输出
Started
12 : /a/b/c.txt
13 : /a/b/c/d.txt
我正在编写一个 spring 在客户端使用 StompJS 的 websocket 应用程序。
在客户端,我打算发送对象列表,在服务器端,当它映射到 java 对象时,它会将自己转换为 LinkedHashMap
我的客户端代码是
function stomball() {
stompClient.send("/brkr/call", {}, JSON.stringify(listIds));
}
Listids 看起来像
[{
"path": "/a/b/c.txt",
"id": 12
}, {
"path": "/a/b/c/d.txt",
"id": 13
}]
List Id 对象看起来像
public class ListId {
private String path;
private Long id;
//getters and setters...
}
控制器看起来像这样
@MessageMapping("/call" )
@SendTo("/topic/showResult")
public RetObj process(List<ListId> listIds) {
if (!listIds.isEmpty()) {
for(ListId listId: listIds) {
}
}
所以我得到一个 java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.blah.ListId
然而,当我对带有 RestMapping 的普通 Spring 控制器执行相同操作时,它工作正常,是否有任何带有 springs MessageMapping 注释的东西将对象映射到 java 不同于传统方法 我不确定为什么不转换为 ListID
我将它从列表更改为数组,并且有效!这是我做的
@MessageMapping("/call" )
@SendTo("/topic/showResult")
public RetObj process(ListId[] listIds) {
if (!listIds.isEmpty()) {
for(ListId listId: listIds) {
}
}
感谢这个问题ClassCastException: RestTemplate returning List<LinkedHashMap> instead of List<MymodelClass>
我知道这个问题已经得到解答,但这里有另一个解决方案。
要让 Jackson 将您的 JSON 数组转换为列表,您必须将其包装在另一个对象中,然后 serialize/deserialize 该对象。
因此您必须将以下 JSON 发送到服务器
{
list: [
{
"path": "/a/b/c.txt",
"id": 12
}, {
"path": "/a/b/c/d.txt",
"id": 13
}
]
}
列表被包装到另一个对象中。
下面是包装器class
class ServiceRequest {
private List<ListId> list;
public List<ListId> getList() {
if (list == null) {
list = new ArrayList<ListId>();
}
return list;
}
}
消息方法将变为
@MessageMapping("/call" )
@SendTo("/topic/showResult")
public RetObj process(ServiceRequest request) {
List<ListId> listIds = request.getList();
if (!listIds.isEmpty()) {
for(ListId listId: listIds) {
}
}
}
测试代码
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;
}
}
}
测试输出
Started
12 : /a/b/c.txt
13 : /a/b/c/d.txt