使用Vaadin下载文件时出现JSON响应错误求助
问题:Vaadin中生成CSV下载时出现JSON响应错误
我在Vaadin组件内实现文件下载,点击按钮尝试生成并下载CSV文件,代码如下:
Button button = new Button("Generate"); @Override public void buttonClick(ClickEvent event) { try{ VaadinResponse resp = VaadinService.getCurrentResponse(); HttpServletResponse response = (HttpServletResponse) resp; response.setContentType("text/csv"); response.setHeader("Content-Disposition", "attachment; filename=\"Report.csv\""); OutputStream outputStream = response.getOutputStream(); String outputResult = "Id,name,dept,salary\n"; outputStream.write(outputResult.getBytes()); outputStream.flush(); outputStream.close(); }catch(Exception e){ e.printStackTrace(); }
点击按钮后出现错误提示:Invalid JSON response from server:Id,name,dept,salary
问题原因及解决方案
错误原因
Vaadin的按钮点击事件默认通过AJAX请求与服务器交互,服务器需要返回符合规范的JSON响应完成前端状态同步。你直接往HttpServletResponse的输出流写入CSV内容,破坏了Vaadin的响应格式,导致前端无法解析响应,抛出JSON格式错误。
正确实现方式
Vaadin提供了专门的文件下载API,无需直接操作底层响应对象,推荐使用StreamResource实现:
Button button = new Button("Generate"); button.addClickListener(event -> { // 创建CSV内容的流资源 StreamResource csvResource = new StreamResource("Report.csv", () -> { String outputResult = "Id,name,dept,salary\n"; return new ByteArrayInputStream(outputResult.getBytes()); }); // 设置内容类型 csvResource.setContentType("text/csv"); // 触发浏览器下载 UI.getCurrent().download(csvResource); });
说明
这种方式由Vaadin统一处理请求流程:点击按钮后,Vaadin会触发浏览器发起专门的文件下载请求,而非复用AJAX响应通道,既不会干扰正常的组件状态同步,也能正确触发浏览器的文件保存行为。
内容的提问来源于stack exchange,提问作者Abikrish
相关产品推荐
相关产品推荐

