私のアプリケーションはテキストファイルを送信する必要があり、それを最初に文字列として生成する必要があります。テキストには非ASCII記号が含まれているため、UTF-8にしたいと思います。私は多くの亜種を試しましたが、添付ファイルがいくつかの疑問符であるため、受け取るすべてのものです。そして、メッセージ本文と同じテキストを送信すると、問題なく動作します。
以下は、添付ファイル付きのMimeBodyPartを生成するコード行です。
_String attachment = "Привет";
messageBodyPart.setContent(new String(attachment.getBytes("UTF-8"),
"UTF-8"),"text/plain; charset=UTF-8");
_
また、変換なしで文字列を使用してみましたが、バイトのみを使用しています。今、ご覧のとおり、バイトから文字列を生成しようとしています...
何が悪いのですか? (私はこれを別のプロジェクトで実行したことを覚えていますが、これは機能しますが、ソースコードにアクセスできなくなります)。
前もって感謝します。ティモフェイ。
[〜#〜]更新[〜#〜]
あなたの返信を読んだ後、さらにいくつかの失敗した実験の後で、私は私の郵送物のコードを公開するのが最善だと思いました。メーリングを行うMailer
クラスがあり、他のクラスはその静的sendMessage()
メソッドを呼び出すだけでメッセージを送信できます。また、すべてGoogle App Engineで実行されます。
_public static void sendMessage(String to, String subject, String msgBody,
String attachment) throws AddressException, MessagingException {
Properties props = new Properties();
Session mailSession = Session.getDefaultInstance(props, null);
Message msg = new MimeMessage(mailSession);
String email = "bla-bla-bla"; // userService.getCurrentUser().getEmail();
msg.setFrom(new InternetAddress(email));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
InternetAddress[] addresses = { new InternetAddress("bla-bla-bla") };
msg.setReplyTo(addresses);
msg.setSubject(subject);
Calendar cal = Calendar.getInstance();
String fileName = cal.get(Calendar.YEAR) + "_"
+ cal.get(Calendar.MONTH) + "_"
+ cal.get(Calendar.DAY_OF_MONTH) + "_"
+ cal.get(Calendar.HOUR_OF_DAY) + "_"
+ cal.get(Calendar.MINUTE) + "_" + cal.get(Calendar.SECOND)
+ "_" + cal.get(Calendar.MILLISECOND) + ".txt";
// create the message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
// fill message
// Here we should have the msgBody.
// Sending attachment contents for debugging only.
messageBodyPart.setText(attachment + " - 4", "UTF-8", "plain");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
MimeBodyPart att = new MimeBodyPart();
att.setText(attachment, "UTF-8", "plain");
att.addHeader("Content-Type", "text/plain; charset=UTF-8");
att.setFileName(fileName);
multipart.addBodyPart(att);
// Put parts in message
msg.setContent(multipart);
Transport.send(msg);
}
_
そして、これを別のクラスで呼び出す行は次のとおりです。
_Mailer.sendMessage("[email protected]", "Test", "No body", "Привет, Я кусок текста");
_
そして、奇妙なことに、メールの元のソースは(見たところ無関係なヘッダーは省いています):
_Message-ID: <[email protected]>
Date: Sat, 12 Feb 2011 11:21:01 +0000
Subject: Pages
From: [email protected]
To: [email protected]
Content-Type: multipart/mixed; boundary=00163662e7107ccbd4049c1402fa
--00163662e7107ccbd4049c1402fa
Content-Type: text/plain; charset=KOI8-R; format=flowed; delsp=yes
Content-Transfer-Encoding: base64
8NLJ18XULCDxIMvV08/LINTFy9PUwSAtIDQNCg==
--00163662e7107ccbd4049c1402fa
Content-Type: text/plain; charset=US-ASCII; name="2011_1_12_11_21_1_691.txt"
Content-Disposition: attachment; filename="2011_1_12_11_21_1_691.txt"
Content-Transfer-Encoding: base64
Pz8/Pz8/LCA/ID8/Pz8/ID8/Pz8/Pw==
--00163662e7107ccbd4049c1402fa--
_
文字セットがなぜ私が設定しようとしているものと違うのか、そしてどこから来たのか分かりません。
コンテンツタイプを application/octet-stream
に設定します。
MimeBodyPart attachmentPart = new MimeBodyPart();
try {
DataSource ds = new ByteArrayDataSource(attachment.getBytes("UTF-8"), "application/octet-stream");
attachmentPart = new MimeBodyPart();
attachmentPart.setDataHandler(new DataHandler(ds));
}
catch (Exception e) {
Logger.getLogger("Blina").log(Level.SEVERE, Misc.getStackTrace(e));
}
attachmentPart.setFileName(fileName);
multipart.addBodyPart(attachmentPart);
// Put parts in message
msg.setContent(multipart);
同様のケースがあり、次のコードで解決しました:
MimeBodyPart att = new MimeBodyPart();
att.setFileName(MimeUtility.encodeText(fileName));
これは、ファイルの送信に使用するサンプルコードです(エンコードやデータ構造に関係ありません)。
_BodyPart fileBodyPart = new MimeBodyPart();
fileBodyPart.setDataHandler(new DataHandler(fileDataSource));
fileBodyPart.setFileName(attachment.getName());
fileBodyPart.setHeader("Content-Type", fileDataSource.getContentType());
fileBodyPart.setHeader("Content-ID", attachment.getName());
fileBodyPart.setDisposition(Part.INLINE);
_
ここで、fileDataSource
は_javax.activation.DataSource
_(テキストファイルはここにあります)であり、fileBodyPart.setDisposition(Part.INLINE);
(_PART.INLINE
_は、HTMLメールのようにデータソースがメッセージ本文にインライン化されることを意味します、_PART.ATTACHMENT
_は、データソースが添付ファイルであることを意味します)。
お役に立てれば。
問題が本文ではなくファイル名にある場合、次のコードが私の(ヘブライ語)ケースで役立ちました。
MimeBodyPart attachment = new MimeBodyPart();
attachment.setFileName(MimeUtility.encodeText(filename, "UTF-8", null));
これを試してみてください:
String attachment = "Привет";
DataSource ds = new ByteArrayDataSource(attachment, "text/plain; charset=UTF-8");
messageBodyPart.setDataHandler(new DataHandler(ds));
更新:(完全な例)
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Session;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
public class Main {
public static void main(String[] args) throws Exception {
String attachment = "Привет";
DataSource ds = new ByteArrayDataSource(attachment, "text/plain; charset=UTF-8");
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.setDataHandler(new DataHandler(ds));
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setText("Hello this is some text");
MimeMultipart mp = new MimeMultipart("mixed");
mp.addBodyPart(bodyPart);
mp.addBodyPart(attachmentPart);
MimeMessage msg = new MimeMessage((Session)null);
msg.setContent(mp);
msg.writeTo(System.out);
}
}
出力:
Message-ID: <[email protected]>
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_0_1579321858.1297366787792"
------=_Part_0_1579321858.1297366787792
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hello this is some text
------=_Part_0_1579321858.1297366787792
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
0J/RgNC40LLQtdGC
------=_Part_0_1579321858.1297366787792--
これは機能します:
MimeMessage msg = new MimeMessage(session);
msg.setFrom(sendFrom);
msg.setSubject(subject, "utf-8");
msg.setSentDate(new Date());
// create and fill the first message part
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setContent(message,"text/plain; charset=UTF-8");
// mbp1.setContent(message,"text/html; charset=UTF-8"); // with this the attachment will fail
// create the Multipart and its parts to it
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
if (attachment!=null){
// Part two is attachment
MimeBodyPart mbp2 = new MimeBodyPart();
mbp2 = new MimeBodyPart();
DataSource ds = null;
try {
ds = new ByteArrayDataSource(attachment.getBytes("UTF-8"), "application/octet-stream");
} catch (IOException e) {
e.printStackTrace();
}
mbp2.setDataHandler(new DataHandler(ds));
mbp2.addHeader("Content-Type", "text/plain; charset=\"UTF-8\"");
mbp2.addHeader("Content-Transfer-Encoding", "base64");
mbp2.setFileName("attachment.txt");
mbp2.setDisposition(Part.ATTACHMENT);
mp.addBodyPart(mbp2);
}
// add the Multipart to the message
msg.setContent(mp);
msg.saveChanges();
// send the message
Transport.send(msg);
以前はエンコードされたURLでファイル名を送信してみました。そしてそれはGmailのために働きます
messageBodyPart.setFileName(UriUtils.encodePath(attachment.getAttachmentName(), "UTF-8"))
ここに完全なコード:
if (!CollectionUtils.isEmpty(requestMessage.getAttachments())) {
MimeBodyPart messageBodyPart;
String fileName;
File file;
for (Attachment attachment : requestMessage.getAttachments()) {
messageBodyPart = new MimeBodyPart();
fileName = attachment.getAttachmentName();
file = new File(fileName);
FileUtils.writeByteArrayToFile(file, attachment.getAttachment());
messageBodyPart.setDataHandler(new DataHandler(new FileDataSource(file)));
messageBodyPart.setFileName(UriUtils.encodePath(attachment.getAttachmentName(), "UTF-8"));
messageBodyPart.setDisposition(Part.ATTACHMENT);
multipart.addBodyPart(messageBodyPart);
}
}
もう1つの可能性:
String attachment = "älytöntä";
MimeBodyPart part = new MimeBodyPart();
part.setText(attachment, "UTF-8");
part.setDisposition("attachment");
part.setFileName("attachment.txt");
part.setHeader("Content-Transfer-Encoding", "base64");
part.setHeader("Content-type", "text/plain; charset=utf-8");