Grails从URL下载文件异常:添加TFTP上传后下载失效问题
问题分析与解决方案
核心问题:对Grails redirect机制的误解
你之前用redirect实现的“下载”,本质是让客户端直接跳转到厂商URL去下载文件,服务器端本身并没有获取到固件文件的内容。所以当后续执行TFTP上传逻辑时,服务器本地根本不存在这个固件文件,自然会报错。
正确的实现思路
要完成“服务器端下载固件→上传到TFTP”的自动化流程,必须让服务器主动从厂商网站获取文件内容,而不是把下载任务甩给客户端。具体步骤:
- 服务器端用HTTP客户端工具直接下载厂商固件到本地临时文件
- 验证下载文件的完整性(比如检查文件大小、哈希值)
- 用TFTP客户端将本地文件上传到TFTP服务器
- 清理本地临时文件
Grails 示例代码实现
以下是一个简化的Service实现,用到Spring的RestTemplate做HTTP下载,Apache Commons Net的TFTPClient做TFTP上传:
import org.springframework.web.client.RestTemplate import org.springframework.http.HttpMethod import org.apache.commons.net.tftp.TFTPClient import java.io.File import java.io.FileOutputStream import java.io.InputStream class FirmwareAutoUpdateService { void processFirmware(String vendorFirmwareUrl, String tftpServer, int tftpPort, String tftpRemoteFileName) { File tempFirmwareFile = null try { // 1. 服务器端主动下载固件到临时文件 tempFirmwareFile = File.createTempFile("temp_firmware", ".bin") RestTemplate restTemplate = new RestTemplate() restTemplate.execute(vendorFirmwareUrl, HttpMethod.GET, null, { response -> InputStream inputStream = response.body FileOutputStream outputStream = new FileOutputStream(tempFirmwareFile) byte[] buffer = new byte[4096] int bytesRead while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead) } outputStream.flush() outputStream.close() inputStream.close() return null }) // 2. 验证文件完整性(示例:检查文件大小不为0,实际可加哈希校验) if (tempFirmwareFile.length() <= 0) { throw new RuntimeException("固件文件下载不完整,文件大小为0") } // 3. 上传到TFTP服务器 TFTPClient tftpClient = new TFTPClient() tftpClient.connect(tftpServer, tftpPort) FileInputStream tftpInputStream = new FileInputStream(tempFirmwareFile) tftpClient.sendFile(tftpRemoteFileName, TFTPClient.BINARY_MODE, tftpInputStream) tftpInputStream.close() tftpClient.disconnect() println("固件上传TFTP服务器成功") } catch (Exception e) { println("处理失败: ${e.message}") throw e } finally { // 4. 清理临时文件 if (tempFirmwareFile?.exists()) { tempFirmwareFile.delete() } } } }
注意事项
- 若厂商固件URL需要身份认证(比如API密钥、Cookie),需在
RestTemplate中添加对应的请求头 - 确保TFTP服务器允许写入指定路径,且服务器防火墙开放TFTP端口(默认69,UDP协议)
- 可添加日志记录、重试机制来提升流程的稳定性
- 临时文件存储路径可根据服务器配置调整,避免权限问题
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

