You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MimeMessage.writeTo输出流丢失HTML单引号编码,如何解决?

问题:MIME邮件写入输出流时特殊字符(单引号)被替换为问号

我用以下代码把完整MIME邮件(含头信息)写入输出流,用来生成HTTP响应的完整字符串(getContent()仅返回正文,无法满足需求):

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
mimeMessage.writeTo(outputStream);

但当邮件正文包含如下HTML内容时,其中的单引号(’)被替换成了问号(?):

<td class="email_monthlySummaryGraph_subTitle chart-subtitle" style="border: 0; color: #1D1D1D; font-family: Arial, sans-serif; font-size: 16px; line-height: 1.4; margin: 0; padding-bottom: 20px; padding-left: 0; padding-right: 0; padding-top: 0; text-align: center;" align="center">
That’s 5 kWh less than your highest week this month
</td>

我尝试过用下面的代码设置编码,但发现此时字符已经被替换,无法解决问题:

String response =
                new String(
                        ((ByteArrayOutputStream) resp).toByteArray(), StandardCharsets.UTF_8);

请问怎么在写入输出流时设置正确编码,避免这个问题?


解决方案

核心原因

mimeMessage.writeTo()会按MIME邮件自身指定的编码输出内容,如果邮件的Content-Type字符编码或Content-Transfer-Encoding设置不当(比如使用ASCII而非UTF-8),特殊字符会被替换为问号。后期转字符串时再指定UTF-8已无济于事,因为字节流中已经是错误内容。

具体解决步骤

  • 确保MIME邮件本身使用UTF-8编码
    创建或解析邮件时,明确设置字符编码为UTF-8:

    // 创建MIME邮件时设置编码
    mimeMessage.setContent(htmlContent, "text/html; charset=UTF-8");
    mimeMessage.setHeader("Content-Transfer-Encoding", "quoted-printable"); // 或base64,确保支持UTF-8
    
    // 解析已有邮件时修正编码
    if (mimeMessage.getContentType() != null && !mimeMessage.getContentType().contains("charset=UTF-8")) {
        mimeMessage.setHeader("Content-Type", mimeMessage.getContentType() + "; charset=UTF-8");
    }
    
  • 使用邮件声明的编码转换字节流
    若邮件编码已正确,writeTo()输出的字节流符合编码要求,转字符串时需使用邮件指定的编码,而非硬编码UTF-8:

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    mimeMessage.writeTo(outputStream);
    
    // 获取邮件实际字符编码
    String charset = "UTF-8"; // 默认值
    if (mimeMessage.getContentType() != null) {
        String[] parts = mimeMessage.getContentType().split("charset=");
        if (parts.length > 1) {
            charset = parts[1].split(";")[0].trim();
        }
    }
    
    String response = new String(outputStream.toByteArray(), charset);
    
  • 避免不必要的编码转换
    全程保证字节流编码与邮件声明一致,若邮件Content-Transfer-Encoding为quoted-printable或base64,writeTo()会自动处理编码,无需额外干预,只需转字符串时用对字符集即可。


内容的提问来源于stack exchange,提问作者Srinidhi Murthy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:22:29