EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

SMTP経由でのメール送信時の文字数制限及び対処について

あるフォームで入力文字数の拡張を行い、その内容をSMTP(postfix)経由でメール送信したところ1000文字付近で文字化けが発生しました。 そこで、本内容についての原因及び対処方法を紹介します。

SMTPの1行あたりの文字数制限について

メールサーバ間でやり取りされるメッセージ形式を定めた標準仕様「RFC 5322:Internet Message Format」には、1行辺りの長さを制限した内容が記載されています。
記載内容によると、改行コードを除いた1行あたりの文字数は998文字以内とすることが必須であり、78文字以内を推奨としています。
SMTPサーバーは上記制限値を超えた場合カットされる場合があり、文字化けの原因となります。

srgia.com

文字数制限の対処について

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;
}