télécharger le courrier en pièce jointe avec Java
j'ai regardé dans le doc de référence, et Spring semble avoir un assez bon support pour envoyer du courrier. Cependant, je dois me connecter à un compte mail, lire les messages, et télécharger toutes les pièces jointes. Est-ce que le téléchargement de pièces jointes de courrier électronique est pris en charge par L'API de courrier électronique de printemps?
je sais que vous pouvez faire cela avec L'API Java Mail, mais dans le passé j'ai trouvé cela très verbeux et désagréable de travailler avec.
EDIT : j'ai reçu plusieurs réponses pointant vers des tutoriels qui décrivent comment envoyer du courrier avec des pièces jointes, mais ce que je demande c'est comment lire pièces jointes de reçu courrier.
santé, Don
6 réponses
Voici la classe que j'utilise pour télécharger des e-mails (avec le traitement des pièces jointes). Vous aurez à regarder par certains des trucs qu'il fait (comme Ignorer les classes de journalisation et la base de données écrit). J'ai aussi renommé certains paquets pour en faciliter la lecture.
l'idée générale est que toutes les pièces jointes sont sauvegardées sous forme de fichiers individuels dans le système de fichiers, et chaque e-mail est sauvegardé sous forme d'enregistrement dans la base de données avec un ensemble d'enregistrements enfants qui pointent vers tous les l'attachement de chemins d'accès.
Focus sur la méthode doEMailDownload.
/**
* Copyright (c) 2008 Steven M. Cherry
* All rights reserved.
*/
package utils.scheduled;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.Properties;
import java.util.Vector;
import javax.mail.Address;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeBodyPart;
import glob.ActionLogicImplementation;
import glob.IOConn;
import glob.log.Log;
import logic.utils.sql.Settings;
import logic.utils.sqldo.EMail;
import logic.utils.sqldo.EMailAttach;
/**
* This will connect to our incoming e-mail server and download any e-mails
* that are found on the server. The e-mails will be stored for further processing
* in our internal database. Attachments will be written out to separate files
* and then referred to by the database entries. This is intended to be run by
* the scheduler every minute or so.
*
* @author Steven M. Cherry
*/
public class DownloadEMail implements ActionLogicImplementation {
protected String receiving_host;
protected String receiving_user;
protected String receiving_pass;
protected String receiving_protocol;
protected boolean receiving_secure;
protected String receiving_attachments;
/** This will run our logic */
public void ExecuteRequest(IOConn ioc) throws Exception {
Log.Trace("Enter");
Log.Debug("Executing DownloadEMail");
ioc.initializeResponseDocument("DownloadEMail");
// pick up our configuration from the server:
receiving_host = Settings.getValue(ioc, "server.email.receiving.host");
receiving_user = Settings.getValue(ioc, "server.email.receiving.username");
receiving_pass = Settings.getValue(ioc, "server.email.receiving.password");
receiving_protocol = Settings.getValue(ioc, "server.email.receiving.protocol");
String tmp_secure = Settings.getValue(ioc, "server.email.receiving.secure");
receiving_attachments = Settings.getValue(ioc, "server.email.receiving.attachments");
// sanity check on the parameters:
if(receiving_host == null || receiving_host.length() == 0){
ioc.SendReturn();
ioc.Close();
Log.Trace("Exit");
return; // no host defined.
}
if(receiving_user == null || receiving_user.length() == 0){
ioc.SendReturn();
ioc.Close();
Log.Trace("Exit");
return; // no user defined.
}
if(receiving_pass == null || receiving_pass.length() == 0){
ioc.SendReturn();
ioc.Close();
Log.Trace("Exit");
return; // no pass defined.
}
if(receiving_protocol == null || receiving_protocol.length() == 0){
Log.Debug("EMail receiving protocol not defined, defaulting to POP");
receiving_protocol = "POP";
}
if(tmp_secure == null ||
tmp_secure.length() == 0 ||
tmp_secure.compareToIgnoreCase("false") == 0 ||
tmp_secure.compareToIgnoreCase("no") == 0
){
receiving_secure = false;
} else {
receiving_secure = true;
}
if(receiving_attachments == null || receiving_attachments.length() == 0){
Log.Debug("EMail receiving attachments not defined, defaulting to ./email/attachments/");
receiving_attachments = "./email/attachments/";
}
// now do the real work.
doEMailDownload(ioc);
ioc.SendReturn();
ioc.Close();
Log.Trace("Exit");
}
protected void doEMailDownload(IOConn ioc) throws Exception {
// Create empty properties
Properties props = new Properties();
// Get the session
Session session = Session.getInstance(props, null);
// Get the store
Store store = session.getStore(receiving_protocol);
store.connect(receiving_host, receiving_user, receiving_pass);
// Get folder
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
try {
// Get directory listing
Message messages[] = folder.getMessages();
for (int i=0; i < messages.length; i++) {
// get the details of the message:
EMail email = new EMail();
email.fromaddr = messages[i].getFrom()[0].toString();
Address[] to = messages[i].getRecipients(Message.RecipientType.TO);
email.toaddr = "";
for(int j = 0; j < to.length; j++){
email.toaddr += to[j].toString() + "; ";
}
Address[] cc;
try {
cc = messages[i].getRecipients(Message.RecipientType.CC);
} catch (Exception e){
Log.Warn("Exception retrieving CC addrs: %s", e.getLocalizedMessage());
cc = null;
}
email.cc = "";
if(cc != null){
for(int j = 0; j < cc.length; j++){
email.cc += cc[j].toString() + "; ";
}
}
email.subject = messages[i].getSubject();
if(messages[i].getReceivedDate() != null){
email.received_when = new Timestamp(messages[i].getReceivedDate().getTime());
} else {
email.received_when = new Timestamp( (new java.util.Date()).getTime());
}
email.body = "";
Vector<EMailAttach> vema = new Vector<EMailAttach>();
Object content = messages[i].getContent();
if(content instanceof java.lang.String){
email.body = (String)content;
} else if(content instanceof Multipart){
Multipart mp = (Multipart)content;
for (int j=0; j < mp.getCount(); j++) {
Part part = mp.getBodyPart(j);
String disposition = part.getDisposition();
if (disposition == null) {
// Check if plain
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {
Log.Debug("Mime type is plain");
email.body += (String)mbp.getContent();
} else {
Log.Debug("Mime type is not plain");
// Special non-attachment cases here of
// image/gif, text/html, ...
EMailAttach ema = new EMailAttach();
ema.name = decodeName(part.getFileName());
File savedir = new File(receiving_attachments);
savedir.mkdirs();
File savefile = File.createTempFile("emailattach", ".atch", savedir );
ema.path = savefile.getAbsolutePath();
ema.size = part.getSize();
vema.add(ema);
ema.size = saveFile(savefile, part);
}
} else if ((disposition != null) &&
(disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE) )
){
// Check if plain
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {
Log.Debug("Mime type is plain");
email.body += (String)mbp.getContent();
} else {
Log.Debug("Save file (%s)", part.getFileName() );
EMailAttach ema = new EMailAttach();
ema.name = decodeName(part.getFileName());
File savedir = new File(receiving_attachments);
savedir.mkdirs();
File savefile = File.createTempFile("emailattach", ".atch", savedir );
ema.path = savefile.getAbsolutePath();
ema.size = part.getSize();
vema.add(ema);
ema.size = saveFile( savefile, part);
}
}
}
}
// Insert everything into the database:
logic.utils.sql.EMail.insertEMail(ioc, email);
for(int j = 0; j < vema.size(); j++){
vema.get(j).emailid = email.id;
logic.utils.sql.EMail.insertEMailAttach(ioc, vema.get(j) );
}
// commit this message and all of it's attachments
ioc.getDBConnection().commit();
// Finally delete the message from the server.
messages[i].setFlag(Flags.Flag.DELETED, true);
}
// Close connection
folder.close(true); // true tells the mail server to expunge deleted messages.
store.close();
} catch (Exception e){
folder.close(true); // true tells the mail server to expunge deleted messages.
store.close();
throw e;
}
}
protected int saveFile(File saveFile, Part part) throws Exception {
BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(saveFile) );
byte[] buff = new byte[2048];
InputStream is = part.getInputStream();
int ret = 0, count = 0;
while( (ret = is.read(buff)) > 0 ){
bos.write(buff, 0, ret);
count += ret;
}
bos.close();
is.close();
return count;
}
protected String decodeName( String name ) throws Exception {
if(name == null || name.length() == 0){
return "unknown";
}
String ret = java.net.URLDecoder.decode( name, "UTF-8" );
// also check for a few other things in the string:
ret = ret.replaceAll("=\?utf-8\?q\?", "");
ret = ret.replaceAll("\?=", "");
ret = ret.replaceAll("=20", " ");
return ret;
}
}
j'ai un peu travaillé sur L'exemple de Steven et j'ai enlevé les parties du code spécifique à Steven. Mon code ne lira pas le corps d'un e-mail s'il y a des pièces jointes. C'est très bien pour mon cas, mais vous pouvez l'affiner davantage pour le vôtre.
package utils;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeBodyPart;
public class IncomingMail {
public static List<Email> downloadPop3(String host, String user, String pass, String downloadDir) throws Exception {
List<Email> emails = new ArrayList<Email>();
// Create empty properties
Properties props = new Properties();
// Get the session
Session session = Session.getInstance(props, null);
// Get the store
Store store = session.getStore("pop3");
store.connect(host, user, pass);
// Get folder
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
try {
// Get directory listing
Message messages[] = folder.getMessages();
for (int i = 0; i < messages.length; i++) {
Email email = new Email();
// from
email.from = messages[i].getFrom()[0].toString();
// to list
Address[] toArray = messages[i] .getRecipients(Message.RecipientType.TO);
for (Address to : toArray) { email.to.add(to.toString()); }
// cc list
Address[] ccArray = null;
try {
ccArray = messages[i] .getRecipients(Message.RecipientType.CC);
} catch (Exception e) { ccArray = null; }
if (ccArray != null) {
for (Address c : ccArray) {
email.cc.add(c.toString());
}
}
// subject
email.subject = messages[i].getSubject();
// received date
if (messages[i].getReceivedDate() != null) {
email.received = messages[i].getReceivedDate();
} else {
email.received = new Date();
}
// body and attachments
email.body = "";
Object content = messages[i].getContent();
if (content instanceof java.lang.String) {
email.body = (String) content;
} else if (content instanceof Multipart) {
Multipart mp = (Multipart) content;
for (int j = 0; j < mp.getCount(); j++) {
Part part = mp.getBodyPart(j);
String disposition = part.getDisposition();
if (disposition == null) {
MimeBodyPart mbp = (MimeBodyPart) part;
if (mbp.isMimeType("text/plain")) {
// Plain
email.body += (String) mbp.getContent();
}
} else if ((disposition != null) && (disposition.equals(Part.ATTACHMENT) || disposition .equals(Part.INLINE))) {
// Check if plain
MimeBodyPart mbp = (MimeBodyPart) part;
if (mbp.isMimeType("text/plain")) {
email.body += (String) mbp.getContent();
} else {
EmailAttachment attachment = new EmailAttachment();
attachment.name = decodeName(part.getFileName());
File savedir = new File(downloadDir);
savedir.mkdirs();
// File savefile = File.createTempFile( "emailattach", ".atch", savedir);
File savefile = new File(downloadDir,attachment.name);
attachment.path = savefile.getAbsolutePath();
attachment.size = saveFile(savefile, part);
email.attachments.add(attachment);
}
}
} // end of multipart for loop
} // end messages for loop
emails.add(email);
// Finally delete the message from the server.
messages[i].setFlag(Flags.Flag.DELETED, true);
}
// Close connection
folder.close(true); // true tells the mail server to expunge deleted messages
store.close();
} catch (Exception e) {
folder.close(true); // true tells the mail server to expunge deleted
store.close();
throw e;
}
return emails;
}
private static String decodeName(String name) throws Exception {
if (name == null || name.length() == 0) {
return "unknown";
}
String ret = java.net.URLDecoder.decode(name, "UTF-8");
// also check for a few other things in the string:
ret = ret.replaceAll("=\?utf-8\?q\?", "");
ret = ret.replaceAll("\?=", "");
ret = ret.replaceAll("=20", " ");
return ret;
}
private static int saveFile(File saveFile, Part part) throws Exception {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(saveFile));
byte[] buff = new byte[2048];
InputStream is = part.getInputStream();
int ret = 0, count = 0;
while ((ret = is.read(buff)) > 0) {
bos.write(buff, 0, ret);
count += ret;
}
bos.close();
is.close();
return count;
}
}
vous avez aussi besoin de ces deux classes helper
package utils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Email {
public Date received;
public String from;
public List<String> to = new ArrayList<String>();
public List<String> cc = new ArrayList<String>();
public String subject;
public String body;
public List<EmailAttachment> attachments = new ArrayList<EmailAttachment>();
}
et
package utils;
public class EmailAttachment {
public String name;
public String path;
public int size;
}
j'ai utilisé ceci pour tester les classes ci-dessus
package utils;
import java.util.List;
public class Test {
public static void main(String[] args) {
String host = "some host";
String user = "some user";
String pass = "some pass";
String downloadDir = "/Temp";
try {
List<Email> emails = IncomingMail.downloadPop3(host, user, pass, downloadDir);
for ( Email email : emails ) {
System.out.println(email.from);
System.out.println(email.subject);
System.out.println(email.body);
List<EmailAttachment> attachments = email.attachments;
for ( EmailAttachment attachment : attachments ) {
System.out.println(attachment.path+" "+attachment.name);
}
}
} catch (Exception e) { e.printStackTrace(); }
}
}
plus info peut être trouvé à http://java.sun.com/developer/onlineTraining/JavaMail/contents.html
Voici une erreur:
else if ((disposition != null) && (disposition.equals(Part.ATTACHMENT)
|| disposition.equals(Part.INLINE) )
il devrait être:
else if ((disposition.equalsIgnoreCase(Part.ATTACHMENT)
|| disposition.equalsIgnoreCase(Part.INLINE))
Merci @Stevenmcherry pour votre réponse
J'ai utilisé Apache Commons Mail pour cette tâche:
import java.util.List;
import javax.activation.DataSource;
import javax.mail.internet.MimeMessage;
import org.apache.commons.mail.util.MimeMessageParser;
public List<DataSource> getAttachmentList(MimeMessage message) throws Exception {
msgParser = new MimeMessageParser(message);
msgParser.parse();
return msgParser.getAttachmentList();
}
D'un objet DataSource
vous pouvez récupérer un InputStream
(à côté du nom et du type) de la pièce jointe (voir API: http://docs.oracle.com/javase/6/docs/api/javax/activation/DataSource.html?is-external=true ).
Jusqu'à présent, je n'ai utilisé que les API JavaMail (et j'en ai été raisonnablement satisfait pour mes besoins). Si le paquet JavaMail complet est trop lourd pour vous, le moteur de transport sous-jacent peut être utilisé sans les couches supérieures du paquet. Plus vous allez dans les piles SMTP, POP3 et IMAP, plus vous devez être prêt à faire pour vous-même.
du bon côté, vous serez également en mesure d'ignorer les pièces qui ne sont pas nécessaires pour votre application.
import java.io.IOException;
import java.io.InputStream;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamSource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
@Controller
@RequestMapping("/sendEmail.do")
public class SendEmailAttachController {
@Autowired
private JavaMailSender mailSender;
@RequestMapping(method = RequestMethod.POST)
public String sendEmail(HttpServletRequest request,
final @RequestParam CommonsMultipartFile attachFile) {
// Input here
final String emailTo = request.getParameter("mailTo");
final String subject = request.getParameter("subject");
final String yourmailid = request.getParameter("yourmail");
final String message = request.getParameter("message");
// Logging
System.out.println("emailTo: " + emailTo);
System.out.println("subject: " + subject);
System.out.println("Your mail id is: "+yourmailid);
System.out.println("message: " + message);
System.out.println("attachFile: " + attachFile.getOriginalFilename());
mailSender.send(new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper messageHelper = new MimeMessageHelper(
mimeMessage, true, "UTF-8");
messageHelper.setTo(emailTo);
messageHelper.setSubject(subject);
messageHelper.setReplyTo(yourmailid);
messageHelper.setText(message);
// Attachment with mail
String attachName = attachFile.getOriginalFilename();
if (!attachFile.equals("")) {
messageHelper.addAttachment(attachName, new InputStreamSource() {
@Override
public InputStream getInputStream() throws IOException {
return attachFile.getInputStream();
}
});
}
}
});
return "Result";
}
}