Vaadin 23中使用@ClientCallable传递Book对象报错原因咨询
Vaadin 23中@ClientCallable接收自定义对象时的类型错误问题
问题场景
使用Vaadin 23框架,通过属性向客户端传递Book对象列表后,尝试用@ClientCallable注解的方法接收客户端返回的Book对象时,触发类型错误。
错误信息
java.lang.IllegalArgumentException: Class 'com.lib.web.business.book.BookDetailDesign' has the method 'onClickBook' whose parameter 0 refers to unsupported type 'com.lib.web.business.book.entities.Book'
相关代码
Book实体类
public class Book implements Serializable { private static final long serialVersionUID = 1L; private int idBook; private String name; }
@ClientCallable方法(原代码)
@ClientCallable public void onBookClicking(Book b) { System.out.println("BookID: "+q.getIdBook( ) ); System.out.println("Category: "+q.getCategory( ) ); getUI( ).ifPresent( ui -> ui.navigate( BookDetailDesign.class, URLEncoder.encode( b.getName( ).replace( "?", "%3F" ), StandardCharsets.UTF_8 ) ) ); }
解决方案
Vaadin的@ClientCallable方法不支持直接接收自定义实体类作为参数,客户端只能传递基础数据类型或JSON字符串,可通过以下两种方式解决:
方式一:传递JSON字符串并解析
- 前端将选中的
Book对象序列化为JSON字符串后传递给服务端 - 服务端修改方法接收String参数,用Jackson等工具反序列化为
Book实例:
@ClientCallable public void onBookClicking(String bookJson) { ObjectMapper objectMapper = new ObjectMapper(); try { Book b = objectMapper.readValue(bookJson, Book.class); System.out.println("BookID: " + b.getIdBook()); getUI().ifPresent(ui -> ui.navigate(BookDetailDesign.class, URLEncoder.encode(b.getName().replace("?", "%3F"), StandardCharsets.UTF_8))); } catch (JsonProcessingException e) { e.printStackTrace(); } }
方式二:传递唯一标识重新查询
如果不需要完整对象,可只传递idBook,服务端根据ID从数据库或缓存中获取完整Book实例:
@ClientCallable public void onBookClicking(int bookId) { // 示例:通过Repository查询Book Book b = bookRepository.findById(bookId).orElse(null); if (b != null) { System.out.println("BookID: " + b.getIdBook()); getUI().ifPresent(ui -> ui.navigate(BookDetailDesign.class, URLEncoder.encode(b.getName().replace("?", "%3F"), StandardCharsets.UTF_8))); } }
内容的提问来源于stack exchange,提问作者lsa
相关产品推荐
相关产品推荐

