2011-02-10 31 views
18

Ứng dụng của tôi phải gửi một tệp văn bản mà trước tiên nó phải tạo dưới dạng Chuỗi. Văn bản chứa các ký hiệu không phải ASCII, vì vậy tôi muốn nó là UTF-8. Tôi đã thử rất nhiều biến thể, nhưng tất cả những gì tôi nhận được dưới dạng tệp đính kèm là một số dấu hỏi. Và, khi tôi gửi cùng một văn bản với nội dung thư, nó hoạt động tốt.JavaMail gửi tệp đính kèm thư từ chuỗi - mã hóa UTF-8

Đây là dòng mã mà tạo ra các MimeBodyPart với tập tin đính kèm:

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

Tôi cũng đã cố gắng sử dụng các chuỗi mà không cần bất kỳ biến đổi, chỉ sử dụng các byte, bây giờ, như bạn thấy, tôi đang cố gắng để tạo chuỗi từ các byte ...

Tôi đang làm gì sai? (Và tôi nhớ làm điều này trong một dự án khác, hoạt động, nhưng tôi không còn có quyền truy cập vào mã nguồn của nó nữa).

Cảm ơn bạn trước. Timofey.

CẬP NHẬT

Sau khi đọc trả lời của bạn, và sau một số sai nữa thử nghiệm tôi nghĩ rằng nó tốt nhất để công bố các quy tắc điều chỉ gửi thư của tôi. Tôi có các lớp học Mailer, mà không gửi thư, và các lớp khác chỉ có thể gọi phương thức tĩnh sendMessage() của chúng tôi để gửi tin nhắn. Và tất cả đều chạy trên 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); 
} 

Và dòng mà các cuộc gọi điều này trong lớp học khác là:

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

Và nguồn nguyên liệu của thư, lạ đủ, là (bỏ đi phần đầu dường như không liên quan):

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

Tôi không hiểu, tại sao các bộ ký tự khác với những gì tôi đang cố gắng đặt và chúng đến từ đâu.

+0

Bạn có thấy mã hóa char chính xác trong tập tin mà bạn đã tạo ra? – JSS

+0

Không. Trong tệp được tạo, tôi chỉ thấy các dấu chấm hỏi. – Ibolit

Trả lời

19

Yippie !!!

Cuối cùng tôi đã làm được!Nói tóm lại, không thiết lập các kiểu nội dung để "text/plain", đặt nó là "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

Bạn có thể chấp nhận câu trả lời của riêng mình ... :-) – PhiLho

+0

Cảm ơn! Tôi quên quay trở lại sau 21 giờ :) – Ibolit

0

này cung cấp cho một thử:

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

CẬP NHẬT: (đầy đủ ví dụ)

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

đầu ra:

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

Tôi vừa thử nó, và nó không hoạt động, cũng không ... = new ByteArrayDataSource (attachment.getBytes ("UTF-8") ... – Ibolit

+0

bạn có thể đăng nguồn gốc của email đã nhận không? – dnault

+0

cũng vậy, nếu bạn không nhận được câu trả lời ở đây, hãy thử các diễn đàn JavaMail Bill Shannon cung cấp một mức hỗ trợ tuyệt vời http://forums.oracle.com/forums/forum.jspa?forumID=975 – dnault

2

Đây là một mẫu mã mà tôi sử dụng để gửi các file (không phân biệt mã hóa hoặc cấu trúc dữ liệu).

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

đâu fileDataSource là một javax.activation.DataSource (file văn bản sẽ được ở đây), và fileBodyPart.setDisposition(Part.INLINE); (PART.INLINE nghĩa nguồn dữ liệu được inlined với nội dung thư, giống như các email HTML, PART.ATTACHMENT nghĩa nguồn dữ liệu là một tập tin đính kèm).

Hy vọng điều này sẽ hữu ích.

+0

Vấn đề là tôi không có tệp như vậy, tôi cần có khả năng gửi một chuỗi dưới dạng tệp đính kèm . – Ibolit

+2

Nếu tôi nhớ rõ, bạn có thể sử dụng nguồn Dữ liệu có trong InputStream. Bạn có thể sử dụng một InputStream đã có chuỗi của bạn hoặc vượt qua một tập tin tạm thời có chứa chuỗi của bạn vào nguồn dữ liệu. Tôi sẽ phải cho bạn thấy vào buổi sáng. –

+0

Có tiêu đề mô tả mã hóa tên tệp của tệp đính kèm không? Mỏ hiển thị dưới dạng dấu chấm hỏi khi sử dụng tên tệp không phải Latinh. – theyuv

0

này hoạt động:

 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

Đã trường hợp tương tự, đoạn mã sau giải quyết nó:

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

Nếu vấn đề là trong tên tập tin, chứ không phải trong cơ thể, đoạn mã sau giúp trong tôi (hebrew) trường hợp:

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

Trong trường hợp của tôi, tên tệp đính kèm trong bộ ký tự tiếng Nhật và tôi đã thử trên dòng mã nhưng tôi đang nhận bộ ký tự rác trong email nhận được của mình (không phải tiếng Nhật cũng không ?????). Bạn có thể giúp tôi làm sai được không? – Akshada

0

Thêm một khả năng:

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"); 
Các vấn đề liên quan