Microsoft 社는 2022년 6월 15일 Internet Explorer 11의 지원을 종료했습니다.

Javamail 에서 첨부파일 붙이는 방법에 대해서

제목

Javamail 에서 첨부파일 붙이는 방법에 대해서

1. 한글 파일명 처리방안

파일이름이 길고, 파일이름에 한글이 포함된 파일을 첨부할 때, 다음과 같이 하면 Gmail 과 유사하게 된다.

Gmail 과 비교하면 1 줄의 길이가 조금 더 짧다.

File attach = new File("첨부파일첨부파일첨부파일첨부파일.pdf");
Multipart multipart = new MimeMultipart("mixed");
MimeBodyPart part = new MimeBodyPart();
part.attachFile(attach);
String charset = java.nio.charset.StandardCharsets.UTF_8.name();
String base64EncodedFileName = MimeUtility.encodeText(attach.getName(), charset, "B");
base64EncodedFileName = base64EncodedFileName.replace("?= =?" + charset + "?B?", "?=\r\n\t=?" + charset + "?B?");
String contentType = request.getServletContext().getMimeType(attach.getName()) + ";\r\n";
contentType += "\t";
contentType += "name=\"" + base64EncodedFileName + "\"";
part.setHeader("Content-Type", contentType);
String contentDisposition = part.ATTACHMENT + ";\r\n";
contentDisposition += "\t";
contentDisposition += "filename=\"" + base64EncodedFileName + "\"";
part.setHeader("Content-Disposition", contentDisposition);
multipart.addBodyPart(part);

결과는 다음과 같다.

Content-Type: application/octet-stream;
name="=?UTF-8?B?7LKo67aA7YyM7J287LKo67aA7YyM7J287LKo67aA?=
=?UTF-8?B?7YyM7J287LKo67aA7YyM7J28LnBkZg==?=";
Content-Disposition: attachment;
filename="=?UTF-8?B?7LKo67aA7YyM7J287LKo67aA7YyM7J287LKo67aA?=
=?UTF-8?B?7YyM7J287LKo67aA7YyM7J28LnBkZg==?="

Content-Type 과 Content-Disposition 헤더를 프로그램적으로 처리했는데, 그렇게 하지 않으면 legacy 에서 장애가 보고되거나, name, filename 항목에 이상한 값이 들어간다.

Javamail API 의 한글 문제는 legacy 호환성, 비표준 지원, 버그 중 하나로 보이는데, 명백한 버그는 Jakarta Mail API 에서 개선되기를 기대하고 있다.

2. 삽질의 기록

파일이름과 관련해서 프로그램적으로 아무것도 하지 않으면, Content-Type 의 name 항목은 "name*=UTF-8''" 과 같은 식이고, Content-Disposition 의 filename 항목은 filename*=UTF-8'' 과 같은 식인데, legacy 시스템에서 파일이름이 깨지는 사례가 보고된 적이 있다.

legacy 시스템에서 "UTF-8''" 를 처리하지 못할 수도 있고, 76 제한을 넘기기 때문에, 수신 쪽에서 이메일을 받을 때는 자동 줄바꿈이 된 상태일 수도 있다.

MimeBodyPart.setFileName(MimeUtility.encodeText(attach.getName())) 과 같이 하면, 다음과 같이 된다.

Content-Type: application/octet-stream;
name*0="=?UTF-8?B?7LKo67aA7YyM7J287LKo67aA7YyM7J287LKo67aA?=
=?UTF-8?B?7";
name*1="YyM7J287LKo67aA7YyM7J28LnBkZg==?=";
Content-Disposition: attachment;
filename*0="=?UTF-8?B?7LKo67aA7YyM7J287LKo67aA7YyM7J287LKo67aA?=
=?UTF-8";
filename*1="?B?7YyM7J287LKo67aA7YyM7J28LnBkZg==?="

System.setProperty("mail.mime.encodefilename", "true"); 인 경우 다음과 같이 된다.

Content-Type: application/octet-stream;
name="=?UTF-8?B?7LKo67aA7YyM7J287LKo67aA7YyM7J287LKo67aA?=
=?UTF-8?B?7YyM7J287LKo67aA7YyM7J28LnBkZg==?=";
Content-Disposition: attachment;
filename*0="=?UTF-8?B?7LKo67aA7YyM7J287LKo67aA7YyM7J287LKo67aA?=
=?UTF-8";
filename*1="?B?7YyM7J287LKo67aA7YyM7J28LnBkZg==?="

name 은 정상이지만, filename 항목이 문제가 있다.

이건 버그라고 생각하고 있다.

제목

첨부파일