如何正确编码MimeMessage为字符串以适配Microsoft Graph?
解决Microsoft Graph发送MIME邮件的Base64编码错误
问题根源
- 错误使用了URL安全的Base64编码:
Base64.encodeBase64URLSafeString会将+替换为-、/替换为_,不符合Graph要求的标准Base64格式 - 请求体格式不正确:Graph的
sendMail接口要求传入JSON结构,而非直接传递编码后的字符串,且Content-Type需设为application/json
修正后的代码
1. 正确编码MIME消息
将URL安全编码替换为标准Base64编码,同时移除编码字符串中的换行符:
private void doMyTest(EmailDetails emailDetails, OAuthAccessToken accessToken) { MimeMessage mimeMessage = createMimeMessageEmail(emailDetails, true); String encodedEmail = null; try { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); mimeMessage.writeTo(buffer); byte[] bytes = buffer.toByteArray(); // 标准Base64编码,移除自动生成的换行符 encodedEmail = Base64.encodeBase64String(bytes).replaceAll("\\r?\\n", ""); } catch (Exception e) { throw new RuntimeException(e); } // 后续请求代码见下文 }
2. 修正请求体与请求头
构建Graph要求的JSON结构请求体,设置正确的Content-Type:
try { // 构造符合Graph接口要求的JSON请求体 String jsonBody = String.format( "{\"message\":{\"mimeContent\":{\"contentType\":\"text/html\",\"content\":\"%s\"}},\"saveToSentItems\":true}", encodedEmail ); HttpPost post = new HttpPost("https://graph.microsoft.com/v1.0/me/sendMail"); post.setEntity(new StringEntity(jsonBody, ContentType.APPLICATION_JSON)); post.setHeader("Authorization", "Bearer " + accessToken.getTokenValue()); try (CloseableHttpClient httpclient = HttpClients.createDefault()) { Integer responseCode = httpclient.execute(post, httpResponse -> { int code = httpResponse.getCode(); String responseBody = EntityUtils.toString(httpResponse.getEntity()); if (code != 202) { System.err.println("请求失败:" + responseBody); } return code; }); } } catch (Exception e) { e.printStackTrace(); }
额外注意事项
- 确认
createMimeMessageEmail方法使用的是jakarta.mail包的类,版本需与依赖适配 - Graph的
sendMail接口成功响应为202 Accepted,而非200 OK,需调整判断逻辑 - 若邮件包含附件或多部分内容,需确保
MimeMessage构建完整,编码后内容无损坏
内容的提问来源于stack exchange,提问作者HeronAlgoSearch
相关产品推荐
相关产品推荐

