SMTP経由でのメール送信時の文字数制限及び対処について
あるフォームで入力文字数の拡張を行い、その内容をSMTP(postfix)経由でメール送信したところ1000文字付近で文字化けが発生しました。 そこで、本内容についての原因及び対処方法を紹介します。
SMTPの1行あたりの文字数制限について
メールサーバ間でやり取りされるメッセージ形式を定めた標準仕様「RFC 5322:Internet Message Format」には、1行辺りの長さを制限した内容が記載されています。
記載内容によると、改行コードを除いた1行あたりの文字数は998文字以内とすることが必須であり、78文字以内を推奨としています。
各SMTPサーバーは上記制限値を超えた場合カットされる場合があり、文字化けの原因となります。
文字数制限の対処について
1行あたり998文字以内の制限に対処する為に、指定文字数以上は強制的に改行コード挿入する処理をJavaで作成しました。
※ポイントとしては、文中に改行が含まれている場合、改行している文節単位で文字数がオーバーしていないかチェックを行っております。
/** * 指定の長さで改行を入れる※メール送信時の文字化け対策 * @param string 変換対象文字列 * @param int 改行を挿入する文字数 * @return String 変換後文字列 */ public static String insertLF(String str,int size){ String ret = ""; if(str==null){ return null; } //改行挿入する文字数未満はそのまま返却 if(str.length()<=size){ return str; } //文中の改行でsplitする String array[] = str.split("\n"); int arrayCnt = 1; int arrayLen = array.length; for(String parts:array){ //splitした文節の文字数オーバーチェック if(parts.length()<=size){ //改行挿入する文字数未満の場合そのまま連結 if(arrayLen > arrayCnt){ ret = ret + parts + "\n"; }else{ ret = ret + parts; } arrayCnt++; continue; } //改行挿入する文字数を超えている場合、分割して改行を挿入 int chunks = parts.length() / size + ((parts.length() % size > 0) ? 1 : 0); for(int index = 0, chunkCnt = 1, len = parts.length(); index < len; index += size, chunkCnt++){ if(chunks > chunkCnt || arrayLen > arrayCnt){ ret = ret + parts.substring(index, Math.min(len, index + size)) + "\n"; }else{ ret = ret + parts.substring(index, Math.min(len, index + size)); } } arrayCnt++; } return ret; }