SimpleJavaMail内嵌图片CID不匹配、MIME类型识别异常问题求助
方案1(推荐,无需修改全局配置)
直接使用withEmbeddedImage的三参数重载,绕开FileDataSource的默认逻辑,完全自主控制CID和MIME类型:
for (Map.Entry<String, String> entry : images.entrySet()) { final String path = entry.getKey(); final String cid = entry.getValue(); final File file = FilesService.api.fileFromDbNPath(account.getDatabase(), path); if (!file.exists()) { throw new ApiException(ApiErrorCodes.MailInexistentImage, "database", account.getDatabase(), "path", path); } // 读取文件字节数组 byte[] fileBytes = Files.readAllBytes(file.toPath()); // Java 7+ 原生支持自动探测正确的MIME类型 String mimeType = Files.probeContentType(file.toPath()); // 兜底兼容,防止探测失败的场景 if (mimeType == null) { String fileName = file.getName().toLowerCase(); if (fileName.endsWith(".png")) mimeType = "image/png"; else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) mimeType = "image/jpeg"; else if (fileName.endsWith(".gif")) mimeType = "image/gif"; else throw new ApiException(ApiErrorCodes.MailInvalidImageType, "path", path); } // 调用重载方法,直接指定cid、字节数组、MIME类型,不会自动追加后缀 mailBuilder.withEmbeddedImage(cid, fileBytes, mimeType); }
该方案不依赖FileDataSource的内部逻辑,传入的CID是什么,最终生成的Content-ID就是什么,同时MIME类型由主动指定,不会出现application/octet-stream的识别错误问题。
方案2(保留FileDataSource写法)
如果不想读取字节数组,要保留FileDataSource的用法,做两处修改即可:
- 构造Mailer时关闭SimpleJavaMail自动给CID追加文件后缀的默认行为:
Mailer mailer = MailerBuilder .withSMTPServer("你的SMTP服务器地址", 端口, 账号, 密码) // 关闭自动给嵌入资源追加文件后缀的功能 .withProperty("simplejavamail.email.autoappend.fileextensions", "false") .buildMailer();
- 修正
FileDataSource的MIME类型识别逻辑:
FileTypeMap pngSupportedMap = FileTypeMap.getDefaultFileTypeMap(); // 手动注册PNG的MIME映射,解决默认识别不到的问题 ((MimetypesFileTypeMap)pngSupportedMap).addMimeTypes("image/png png PNG"); for (Map.Entry<String, String> entry : images.entrySet()) { final String path = entry.getKey(); final String cid = entry.getValue(); final File file = FilesService.api.fileFromDbNPath(account.getDatabase(), path); if (!file.exists()) { throw new ApiException(ApiErrorCodes.MailInexistentImage, "database", account.getDatabase(), "path", path); } FileDataSource fileDataSource = new FileDataSource(file); fileDataSource.setFileTypeMap(pngSupportedMap); mailBuilder.withEmbeddedImage(cid, fileDataSource); }
内容的提问来源于stack exchange,提问作者Panais
相关产品推荐
相关产品推荐

