XML Gzip压缩Base64编码后存入数据库报错问题排查
问题解析与修复
问题根源
你当前的代码错误在于直接将Base64OutputStream对象拼接进SQL语句,此时调用的是该对象的默认toString()方法,返回的是类似java.util.Base64$OutputStream@xxxxxxx的对象标识字符串——里面包含的.字符正是数据库报错"invalid symbol '.' found while decoding base64 sequence"的原因。而你硬编码的是实际的Base64编码字符串,所以能正常执行。
修复方案
核心思路是:不要返回输出流对象,而是直接生成并返回Base64编码后的字符串。修改后的代码如下:
1. 重构fileGzipAndBase64方法,返回Base64字符串
public static String fileGzipAndBase64(String fileContent) throws IOException { // 使用ByteArrayOutputStream承接压缩并编码后的内容 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); Base64OutputStream b64os = new Base64OutputStream(baos); GZIPOutputStream gzip = new GZIPOutputStream(b64os)) { gzip.write(fileContent.getBytes(StandardCharsets.UTF_8)); gzip.finish(); // 确保压缩流的所有数据都写入到下层输出流 return baos.toString(StandardCharsets.UTF_8); } catch (Throwable t) { t.printStackTrace(); throw t; // 抛出异常让上层处理,避免静默失败 } }
2. 更新compressAndEncode方法,返回字符串类型结果
public static String compressAndEncode(String file) throws IOException, URISyntaxException { String filePath = getAbsoluteFilePath("test.xml"); String fileContent = Files.readString(Path.of(filePath), StandardCharsets.UTF_8); String gzipBase64 = fileGzipAndBase64(fileContent); LOG.info("gzipBase64: " + gzipBase64); return gzipBase64; }
3. 调整SQL拼接逻辑
String data = TestResourceHelper.compressAndEncode(paymentFile); sql = "insert into file (xml-content) values(decode('" + data + "', 'base64'))";
额外提示
直接拼接字符串到SQL存在SQL注入风险,建议使用PreparedStatement来参数化查询,示例如下:
String sql = "insert into file (xml-content) values(decode(?, 'base64'))"; PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setString(1, data); pstmt.executeUpdate();
内容的提问来源于stack exchange,提问作者Shabar
相关产品推荐
相关产品推荐

