webentwicklung-frage-antwort-db.com.de

JavaMail sendet E-Mail-Anhang von String - Kodierung UTF-8

Meine Anwendung muss eine Textdatei senden, die zuerst als String generiert werden muss. Der Text enthält Nicht-ASCII-Symbole. Ich möchte, dass es UTF-8 ist. Ich habe viele Varianten ausprobiert, aber als Anhang erhalten Sie nur Fragezeichen. Und wenn ich den gleichen Text wie den Nachrichtentext sende, funktioniert das einwandfrei. 

Hier ist die Codezeile, die das MimeBodyPart mit der Anlage generiert:

String attachment = "Привет";
messageBodyPart.setContent(new String(attachment.getBytes("UTF-8"),
    "UTF-8"),"text/plain; charset=UTF-8");

Ich habe auch versucht, den String ohne Transformationen zu verwenden, nur mit den Bytes. Jetzt, wie Sie sehen, versuche ich, einen String aus den Bytes zu generieren ...

Was mache ich falsch? (Und ich erinnere mich, dass ich dies in einem anderen Projekt gemacht habe, das funktioniert, aber ich habe keinen Zugriff mehr auf den Quellcode). 

Vielen Dank im Voraus .. Timofey.

UPDATE

Nachdem ich Ihre Antworten gelesen hatte und nach erfolglosem Experimentieren, dachte ich, dass es am besten wäre, den Code meiner Mailing-Sache zu veröffentlichen. Ich habe die Mailer-Klasse, die das Mailing übernimmt, und andere Klassen können einfach ihre statische sendMessage()-Methode aufrufen, um eine Nachricht zu senden. Und alles läuft auf 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);
}

Und die Zeile, die dieses Ding in einer anderen Klasse aufruft, lautet: 

Mailer.sendMessage("[email protected]", "Test", "No body", "Привет, Я кусок текста");

Und die rohe Quelle der Post ist seltsamerweise (die scheinbar irrelevanten Kopfzeilen wegzulassen): 

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

Ich verstehe es einfach nicht, warum sich die Zeichensätze von meinen Einstellungen unterscheiden und woher sie kommen. 

20
Ibolit

Setzen Sie den Inhaltstyp auf 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);
21
Ibolit

Hatte einen ähnlichen Fall, der folgende Code hat es gelöst:

MimeBodyPart att = new MimeBodyPart();
att.setFileName(MimeUtility.encodeText(fileName));
6
meliniak

Dies ist ein Beispielcode, den ich zum Senden von Dateien verwende (unabhängig von Codierung oder Datenstruktur).

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

Wobei fileDataSource ein javax.activation.DataSource ist (Textdatei wird hier sein), und fileBodyPart.setDisposition(Part.INLINE); (PART.INLINE bedeutet, dass die Datenquelle wie die E-Mail-Nachricht in den Nachrichtentext eingebettet ist, PART.ATTACHMENT bedeutet, dass die Datenquelle eine Anlage ist).

Hoffe das hilft.

2
Buhake Sindi

Wenn das Problem im Dateinamen und nicht im Haupttext liegt, half folgender Code in meinem (hebräischen) Fall: 

MimeBodyPart attachment = new MimeBodyPart();
attachment.setFileName(MimeUtility.encodeText(filename, "UTF-8", null));
1
yurin

Probieren Sie es aus:

String attachment = "Привет";
DataSource ds = new ByteArrayDataSource(attachment, "text/plain; charset=UTF-8");
messageBodyPart.setDataHandler(new DataHandler(ds));

UPDATE: (vollständiges Beispiel)

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

ausgabe:

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--
1
dnault

Das funktioniert:

        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);
0
jankos

Eine weitere Möglichkeit:

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");
0
Iikka