Kotlin+Vaadin14 Grid添加下载按钮出现StreamResource重载歧义如何解决
问题原因
报错是Kotlin SAM转换的重载歧义导致的:StreamResource 提供的两个构造函数的第二个参数都是单抽象方法(SAM)接口,你传入的lambda表达式同时匹配两个接口的方法签名,编译器无法自动判断要调用哪个构造。
另外你当前的getStream函数也存在实现错误:调用file.readBytes()返回的是字节数组,并没有返回符合要求的InputStream,且提前读取全量文件字节会导致大文件场景下内存溢出。
解决方案
1. 显式指定SAM类型消除歧义
直接将lambda声明为InputStreamFactory类型,明确告知编译器选择对应构造函数即可。
2. 修正getStream实现
直接返回文件输入流,不需要提前读取全量内容。
完整可运行代码
首先是Grid列的实现:
// 注意提前导入依赖包:import com.vaadin.flow.server.InputStreamFactory grid.addComponentColumn { item -> val button = Button(item.plandatei) // 显式指定InputStreamFactory消除重载歧义 val resource = StreamResource(item.plandatei, InputStreamFactory { getStream(item.plandatei) }) val anchor = Anchor(resource) anchor.element.setAttribute("download", true) anchor.element.appendChild(button.element) return@addComponentColumn anchor }
修正后的getStream函数:
fun getStream(filename: String): InputStream { // 直接返回文件输入流,避免内存溢出 return File(filename).inputStream() }
额外注意事项
- 可给Anchor添加
target = "_blank"属性,避免下载操作替换当前页面内容 - 务必做好文件名、路径的合法性校验,避免出现任意文件下载的安全漏洞
内容的提问来源于stack exchange,提问作者Twistleton
相关产品推荐
相关产品推荐

