2011-02-10 16 views
18

Mi aplicación debe enviar un archivo de texto, que primero debe generar como una cadena. El texto contiene símbolos que no son ASCII, por lo que me gustaría que fuera UTF-8. He intentado muchas variantes, pero todo lo que recibo como archivo adjunto son algunos signos de interrogación. Y, cuando envío el mismo texto como el cuerpo del mensaje, funciona bien.JavaMail enviando archivos adjuntos de correo de cadena de caracteres UTF-8

Aquí está la línea de código que genera el MimeBodyPart con el accesorio:

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

También probé utilizando la cadena sin ninguna transformación, utilizando sólo los bytes, ahora, como ves, estoy tratando de generar una cadena a partir de los bytes ...

¿Qué estoy haciendo mal? (Y recuerdo haberlo hecho en otro proyecto, que funciona, pero ya no tengo acceso a su código fuente).

Gracias de antemano. Timofey.

ACTUALIZACIÓN

Después de leer sus respuestas, y después de un poco más de éxito experimentar pensé que lo mejor para publicar el código de mi cosa correo. Tengo la clase Mailer, que hace el envío de correos, y otras clases pueden simplemente llamar a su método estático sendMessage() para enviar un mensaje. Y todo se ejecuta en 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); 
} 

Y la línea que llama a esta cosa en otra clase es:

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

Y la fuente prima del correo, por extraño que parezca, es (dejando de lado los encabezados aparentemente irrelevantes):

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

Simplemente no lo entiendo, por qué los conjuntos de caracteres son diferentes de lo que estoy tratando de establecer, y de dónde vienen.

+0

¿Ves correcta codificación de carbón en el archivo que ha generado? – JSS

+0

No. En el archivo generado, solo veo los signos de interrogación. – Ibolit

Respuesta

19

Yippie !!!

¡Finalmente lo hice!En resumen, no establezca el tipo de contenido a "text/plain", otra vez en "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); 
+3

Puede aceptar su propia respuesta ... :-) – PhiLho

+0

¡Gracias! Me olvidé de volver después de las 21 horas :) – Ibolit

0

seguirlo:

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

ACTUALIZACIÓN: (ejemplo completo)

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

de salida:

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

Acabo de probarlo, y no funcionó, ni tampoco ... = new ByteArrayDataSource (attachment.getBytes ("UTF-8") ... – Ibolit

+0

puede publicar la fuente sin procesar del correo electrónico recibido? – dnault

+0

también, Si no obtiene una respuesta aquí, pruebe los foros de JavaMail. Bill Shannon ofrece un increíble nivel de asistencia. http://forums.oracle.com/forums/forum.jspa?forumID=975 – dnault

2

Se trata de un código de ejemplo que utilizo para enviar archivos (independientemente de la codificación o estructura de datos).

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

Dónde fileDataSource es una javax.activation.DataSource (archivo de texto será de aquí), y fileBodyPart.setDisposition(Part.INLINE); (PART.INLINE significa fuente de datos se colocarán en línea con el cuerpo del mensaje, como mensajes de correo electrónico HTML, PART.ATTACHMENT significa fuente de datos es un archivo adjunto).

Espero que esto ayude.

+0

Lo que pasa es que no tengo un archivo como tal, necesito poder enviar un String como archivo adjunto . – Ibolit

+2

Si recuerdo bien, puede usar un origen de datos que tome un InputStream. Puede usar un InputStream que tenga su String o pasar un archivo temporal que contenga su cadena a la fuente de datos. Tendré que mostrártelo por la mañana. –

+0

¿Hay un encabezado que describa la codificación del nombre de archivo del archivo adjunto? Mine muestra como signos de interrogación cuando se utiliza un nombre de archivo no latino. – theyuv

0

esto funciona:

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

Had caso similar, siguiente código resuelto:

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

Si el problema está en el nombre del archivo, en lugar de en el cuerpo, siguiente código ayudó en mi (hebreo) caso:

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

En mi caso, el nombre del archivo adjunto está en japonés y probé la línea de código anterior, pero recibo el conjunto de caracteres de basura en mi correo electrónico recibido (¿ni japonés ni ?????). ¿Puedes por favor ayudarme a hacer lo que estoy haciendo mal? – Akshada

0

una posibilidad más:

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"); 
Cuestiones relacionadas