Hi everyone,
I wrote a little javamail program which sends an email containing attachment(s) and a body content written with special characters (i.e. with accents).
The problem is that when the email is sent, the mail client (like outlook) receive it in the wrong format : uscii, 7 bit encoding.
Simple question : why ?
The following code list all my javamail program :
JMailTest.java :
/*
* Created on 10 janv. 2008
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package javamail;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.mail.MessagingException;
/**
* @author re7v75i
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class JMailTest {
private static final String SMTP_SERVER = "xxxxx";
private static final String FROM = "xxxx@xxxxx.com";
private static final String SUBJECT = "JavaMail Test";
private static final String TO = "xxxxx@xxxxx";
private static MailSenderBean buildMailData() throws IOException {
MailSenderBean data = new MailSenderBean();
String filename = "__________.txt";
File file = new File(filename);
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
byte[][] rawData = new byte[1][];
String[] filenames = new String[1];
String[] TOs = new String[1];
TOs[0] = TO;
filenames[0] = filename;
rawData[0] = buffer;
fis.read(buffer);
data.setAttachmentFilename(filenames);
data.setAttachmentRawData(rawData);
System.out.println(new String(buffer,"UTF-8"));
data.setBody(new String(buffer,"UTF-8"));
data.setFrom(FROM);
data.setSubject(SUBJECT);
data.setTo(TOs);
return data;
}
public static void main(String[] args) {
System.out.println("JavaMail start");
System.setProperty("file.encoding","UTF-8");
System.setProperty("client.encoding","UTF-8");
JMail jmail = new JMail();
try {
MailSenderBean data = JMailTest.buildMailData();
jmail.send(data, SMTP_SERVER);
//jmail.send()
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JavaMail end");
}
}
JMail.java :
/*
* Created on 10 janv. 2008
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package javamail;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
/**
* @author re7v75i
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class JMail {
public JMail() {}
public void send(MailSenderBean mail,
String SMTPServer) throws UnsupportedEncodingException, MessagingException {
MimeMultipart root = new MimeMultipart("mixed");
//build root message
MimeMessage message = buildMessage(mail, root, SMTPServer);
//add body content
addBody(mail, root);
MimeBodyPart text = (MimeBodyPart) root.getBodyPart(0);
try {
System.out.println((String)text.getContent());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//add attachments
addAttachment(mail, root);
//send mail
Transport.send(message);
}
/**
* Build the root body part.
*
* @param mail
* Contains the mail sending parameters.
* @param root
* The root body part.
* @param SMTPServer
* The SMTP server name.
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
private MimeMessage buildMessage(MailSenderBean mail,
MimeMultipart root, String SMTPServer)
throws UnsupportedEncodingException, MessagingException {
System.setProperty("mail.mime.charset", "UTF-8");
Properties props = System.getProperties();
props.put("mail.smtp.host", SMTPServer);
Session session = Session.getInstance(props, null);
MimeMessage message = new MimeMessage(session);
message.addHeaderLine("Content-Type: text/html; charset=UTF-8");
InternetAddress from = new InternetAddress(mail.getFrom());
String[] tos = mail.getTo();
List TOs = new ArrayList();
for (int i = 0; i < tos.length; i++)
if (tos[i] != null)
TOs.add(new InternetAddress(tos));
InternetAddress[] IAs = new InternetAddress[TOs.size()];
for (int i = 0; i < TOs.size(); i++)
IAs[i] = (InternetAddress) TOs.get(i);
message.addRecipients(MimeMessage.RecipientType.TO, IAs);
message.setFrom(from);
message.setSubject(mail.getSubject());
message.setContent(root);
message.saveChanges();
return message;
}
/**
* Add the body content part.
*
* @param mail
* Contains the mail sending parameters.
* @param root
* The root body part.
* @throws MessagingException
*/
private void addBody(MailSenderBean mail,
MimeMultipart root) throws MessagingException {
MimeBodyPart text = new MimeBodyPart();
text.setText(mail.getBody(), "UTF-8");
text.setHeader("MIME-Version", "1.0");
text.setHeader("Content-Type", "text/html");
text.setHeader("Content-Transfert-Encoding", "8bit");
text.setContent(mail.getBody(), "text/html");
root.addBodyPart(text);
}
/**
* Add the attachment part(s).
*
* @param mail
* Contains the mail sending parameters.
* @param root
* The root body part.
* @throws MessagingException
*/
private void addAttachment(MailSenderBean mail,
MimeMultipart root) throws MessagingException {
byte[][] attachments = mail.getAttachmentRawData();
String[] filenames = mail.getAttachmentFilename();
if (attachments != null) {
for (int i = 0; i < attachments.length; i++) {
if (attachments[i] != null) {
byte[] rawData = attachments[i];
MimeBodyPart attachment = new MimeBodyPart();
attachment.setDisposition(Part.ATTACHMENT);
attachment.setDataHandler(new DataHandler(
new ByteArrayDataSource(rawData,
"lotontech/javaobject")));
attachment.setFileName(filenames[i]);
root.addBodyPart(attachment);
}
}
}
}
}
*MailSenderBean.java :*
package javamail;
/**
* This class represents the mail sending parameters. Can specify multiple
* attahments with associated names. Can specify multiple addressees.
*
* @author Fran�ois Fournel
*/
public class MailSenderBean {
private String from = "";
private String subject = "";
private String body = "";
private String[] to = null;
private byte[][] attachmentRawData = null;
private String[] attachmentFilename = null;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String[] getTo() {
return to;
}
public void setTo(String[] to) {
this.to = to;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
if (this.body == null)
this.body = "";
}
public byte[][] getAttachmentRawData() {
return attachmentRawData;
}
public void setAttachmentRawData(byte[][] attachmentRawData) {
this.attachmentRawData = attachmentRawData;
}
public String[] getAttachmentFilename() {
return attachmentFilename;
}
public void setAttachmentFilename(String[] attachmentFilename) {
this.attachmentFilename = attachmentFilename;
}
}
*ByteArrayDataSource.java :*
package javamail;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import javax.activation.DataSource;
/**
*
* Creation date: (03/2004)
* @author: VOLVO IT - Przemyslaw KRUK
*/
public class ByteArrayDataSource implements DataSource {
/** Data. */
private byte[] data;
/** Content-type. */
private String type;
private ByteArrayOutputStream baos;
/**
* Create a datasource from a byte array.
*
* @param data A byte[].
* @param type A String.
*/
public ByteArrayDataSource(byte[] data, String type) {
this.data = data;
this.type = type;
}
/**
* Create a datasource from an input stream.
*
* @param is An InputStream.
* @param type A String.
*/
public ByteArrayDataSource(InputStream is, String type) throws IOException {
this.type = type;
int ch;
ByteArrayOutputStream os = new ByteArrayOutputStream();
BufferedInputStream isReader = new BufferedInputStream(is);
BufferedOutputStream osWriter = new BufferedOutputStream(os);
while ((ch = isReader.read()) != -1) {
osWriter.write(ch);
}
data = os.toByteArray();
}
/**
* Create a datasource from a String.
*
* @param data A String.
* @param type A String.
*/
public ByteArrayDataSource(String data, String type) {
this.type = type;
try {
// Assumption that the string contains only ASCII
// characters! Else just pass in a charset into this
// constructor and use it in getBytes().
this.data = data.getBytes("iso-8859-1");
} catch (UnsupportedEncodingException uex) {
// Do something!
}
}
/**
* Get the content type.
*
* @return A String.
*/
public String getContentType() {
if (type == null)
return "application/octet-stream";
else
return type;
}
/**
* Get the input stream.
*
* @return An InputStream.
* @exception IOException.
*/
public InputStream getInputStream() throws IOException {
if (data == null)
throw new IOException("no data");
return new ByteArrayInputStream(data);
}
/**
* Get the name.
*
* @return A String.
*/
public String getName() {
return "ByteArrayDataSource";
}
/**
* Get the output stream.
*
* @return An OutputStream.
* @exception IOException.
*/
public OutputStream getOutputStream() throws IOException {
baos = new ByteArrayOutputStream();
return baos;
}
}
Thanks for your help.
Edited by: ffl69 on Jan 11, 2008 12:13 AM