Frage JavaMail sendet Mail Anhang von String - Encoding UTF-8


Meine Anwendung muss eine Textdatei senden, die sie als String generieren muss. Der Text enthält Nicht-ASCII-Symbole, also möchte ich, dass es UTF-8 ist. Ich habe viele Varianten ausprobiert, aber alles, was ich als Anhang bekomme, sind ein paar Fragezeichen. Und wenn ich denselben Text wie den Nachrichtentext sende, funktioniert es gut.

Hier ist die Codezeile, die das MimeBodyPart mit dem Anhang generiert:

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

Ich habe auch versucht, die Zeichenfolge ohne irgendwelche Transformationen zu verwenden, nur mit den Bytes, jetzt, wie Sie sehen, ich versuche, eine Zeichenfolge aus den Bytes zu generieren ...

Was mache ich falsch? (Und ich erinnere mich daran, dies in einem anderen Projekt zu tun, das funktioniert, aber ich habe keinen Zugriff mehr auf seinen Quellcode).

Vielen Dank im Voraus. Timofey.

AKTUALISIEREN

Nachdem ich Ihre Antworten gelesen hatte, und nach einigen erfolglosen Experimenten, dachte ich, dass es am besten wäre, den Code meiner Postsendung zu veröffentlichen. ich habe Mailer Klasse, die das Mailing durchführt, und andere Klassen können einfach ihre statische aufrufen sendMessage() Methode zum Senden einer Nachricht. 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 nennt, ist:

Mailer.sendMessage("mymail@example.com", "Test", "No body", "Привет, Я кусок текста");

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

Message-ID: <00163662e7107ccbe3049c1402fb@google.com>
Date: Sat, 12 Feb 2011 11:21:01 +0000
Subject: Pages
From: mymail@example.com
To: mymail@example.com
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 die Zeichensätze anders sind als das, was ich einstellen will und woher sie kommen.


18
2018-02-10 17:31


Ursprung


Antworten:


Yippie !!!

Ich habe es endlich geschafft! Kurz gesagt, setze den Inhaltstyp nicht auf "text / plain", setze ihn 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);

19
2018-02-12 13:50



Hatte ähnlichen Fall, folgenden Code hat es gelöst:

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

6
2018-06-10 08:57



Dies ist ein Beispielcode, mit dem ich Dateien senden kann (unabhängig von der 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);

Woher fileDataSource ist ein javax.activation.DataSource (Textdatei wird hier sein), und fileBodyPart.setDisposition(Part.INLINE); (PART.INLINE bedeutet, dass die Datenquelle wie HTML-E-Mails mit dem Nachrichtentext verknüpft ist. PART.ATTACHMENT bedeutet, Datenquelle ist ein Anhang).

Hoffe das hilft.


2
2018-02-10 18:46



Wenn das Problem im Dateinamen statt im Text liegt, half folgender Code in meinem (hebräischen) Fall:

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

1
2018-02-14 14:32



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: <1439781957.1.1297366787857.JavaMail.dnault@dnault.local>
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--

0
2018-02-10 17:47



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
2017-10-24 21:10



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
2018-02-01 08:38