我正在使用下一代码使用javamail API从我的邮箱帐户下载附件和正文文本,它运行正常。但是,当电子邮件上有内嵌或嵌入图像时,图像不会以文本或附件文件的形式下载。我是Java新手,已经在网上阅读,但没有找到易于理解的实施解决方案。任何workarround或代码来完成它?
这是我正在使用的代码:
public void processMessageBody(Message message) {
try {
Object content = message.getContent();
// check for string
// then check for multipart
if (content instanceof String) {
System.out.println(content);
} else if (content instanceof Multipart) {
Multipart multiPart = (Multipart) content;
procesMultiPart(multiPart);
} else if (content instanceof InputStream) {
InputStream inStream = (InputStream) content;
int ch;
while ((ch = inStream.read()) != -1) {
System.out.write(ch);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
public void procesMultiPart(Multipart content) {
try {
for (int i = 0; i < content.getCount(); i++) {
BodyPart bodyPart = content.getBodyPart(i);
Object o;
o = bodyPart.getContent();
if (o instanceof String) {
System.out.println("Text = " + o);
} else if (null != bodyPart.getDisposition()
&& bodyPart.getDisposition().equalsIgnoreCase(
Part.ATTACHMENT)) {
String fileName = bodyPart.getFileName();
System.out.println("fileName = " + fileName);
InputStream inStream = bodyPart.getInputStream();
FileOutputStream outStream = new FileOutputStream(new File(
downloadDirectory + fileName));
byte[] tempBuffer = new byte[4096];// 4 KB
int numRead;
while ((numRead = inStream.read(tempBuffer)) != -1) {
outStream.write(tempBuffer);
}
inStream.close();
outStream.close();
}
// else?
}
} catch (IOException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
我尝试添加下一个if语句来显示一条消息(如果它是内嵌图像),但没有幸运:
public void procesMultiPart(Multipart content) {
try {
for (int i = 0; i < content.getCount(); i++) {
BodyPart bodyPart = content.getBodyPart(i);
Object o;
o = bodyPart.getContent();
// NOT WORKING
if (o instanceof Image) {
System.out.println("procesMultiPart has Inline Images");
}
//
else if (o instanceof String) {
System.out.println("Text = " + o);
} else if (null != bodyPart.getDisposition()
&& bodyPart.getDisposition().equalsIgnoreCase(
Part.ATTACHMENT)) {
String fileName = bodyPart.getFileName();
System.out.println("fileName = " + fileName);
InputStream inStream = bodyPart.getInputStream();
FileOutputStream outStream = new FileOutputStream(new File(
downloadDirectory + fileName));
byte[] tempBuffer = new byte[4096];// 4 KB
int numRead;
while ((numRead = inStream.read(tempBuffer)) != -1) {
outStream.write(tempBuffer);
}
inStream.close();
outStream.close();
}
// else?
}
} catch (IOException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
答案 0 :(得分:1)
以下代码应该适合您....
private String getAttachments(Message message, HttpServletRequest request) throws MessagingException, IOException {
String contentType = message.getContentType();
String attachFiles="";
if (contentType.contains("multipart")) {
// content may contain attachments
Multipart multiPart = (Multipart) message.getContent();
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
String disposition =part.getDisposition();
String file=part.getFileName();
//External attachments
if (disposition != null && Part.ATTACHMENT.equalsIgnoreCase(disposition)) {
// this part is attachment
String fileName = new Date().getTime()+ "_"+ part.getFileName().replaceAll("[^a-zA-Z0-9\\._]+", "_"); //To make attachment name uniq we are adding current datatime before name.
attachFiles += fileName + ","; //concrete all attachment's name with comma separated.
part.saveFile(new File(request
.getSession()
.getServletContext()
.getRealPath(
"/WEB-INF/attechments/"
+ fileName))); //To save the attachment file at specific location.
// LOG.info("\n\t Path :- " +request.getSession().getServletContext().getRealPath("/WEB-INF/attechments/" + fileName));
}
//Inline Attachments
else if (disposition != null && Part.INLINE.equalsIgnoreCase(disposition)) {
// this part is attachment
String fileName = new Date().getTime()+ "_"+ part.getFileName().replaceAll("[^a-zA-Z0-9\\._]+", "_"); //To make attachment name uniq we are adding current datatime before name.
// attachFiles += fileName + ","; //concrete all attachment's name with comma separated.
part.saveFile(new File(request
.getSession()
.getServletContext()
.getRealPath(
"/WEB-INF/attechments/"
+ fileName))); //To save the attachment file at specific location.
// LOG.info("\n\t Path :- " +request.getSession().getServletContext().getRealPath("/WEB-INF/attechments/" + fileName));
}
//Inline icons and smileys
else if(file != null && disposition==null)
{
String fileName = new Date().getTime()+ "_"+ part.getFileName().replaceAll("[^a-zA-Z0-9\\._]+", "_");
// attachFiles += fileName + ","; //concrete all attachment's name with comma separated.
part.saveFile(new File(request
.getSession()
.getServletContext()
.getRealPath(
"/WEB-INF/attechments/"
+ fileName)));
}
}
}
if (attachFiles.length() > 1) {
attachFiles = attachFiles.substring(0, attachFiles.length() - 1);
}
return attachFiles;
}
答案 1 :(得分:1)
嵌入式图片将成为多部分/相关内容的一部分,不会被标记为附件。有关此类消息的结构,请参阅RFC 2387。
答案 2 :(得分:0)
public static List<String> getAttachmentFileName(MimeMultipart mimeMultipart) throws Exception{
List<String> attachFileNameList = new ArrayList<String>();
int count = mimeMultipart.getCount();
for (int i = 0; i < count; i++) {
BodyPart bodyPart = mimeMultipart.getBodyPart(i);
if("ATTACHMENT".equalsIgnoreCase(bodyPart.getDisposition())){
attachFileNameList.add(bodyPart.getFileName());
}
}
return attachFileNameList;
}
答案 3 :(得分:0)
如果要将内联文件保存到附件中,可以尝试以下代码:
private static void fillBodyAndAttachments(Message message) throws Exception {
String body = "";
List<FileData> attachments = new LinkedList<>();
String contentType = message.getContentType();
if (contentType.contains("text/plain") || contentType.contains("text/html")) {
Object content = message.getContent();
if (content != null) {
body = content.toString();
}
System.out.println(body);
return;
}
if (contentType.contains("multipart")) {
Multipart multiPart = (Multipart) message.getContent();
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
String disposition = part.getDisposition();
if (Part.ATTACHMENT.equalsIgnoreCase(disposition)) {
addAttachment(attachments, part);
} else if (Part.INLINE.equalsIgnoreCase(disposition)) {
Object content = part.getContent();
if (content instanceof InputStream) {
var inputStream = (InputStream) content;
byte[] byteArray = IOUtils.toByteArray(inputStream);
addInlineAttachment(attachments, byteArray, part.getFileName());
}
} else {
Object content = part.getContent();
if (content instanceof String) {
body = (String) content;
} else if (content instanceof InputStream) {
body = new String(IOUtils.toByteArray((InputStream) content));
} else if (content instanceof IMAPNestedMessage) {
IMAPNestedMessage imapNestedMessage = (IMAPNestedMessage) content;
body = new String(IOUtils.toByteArray(imapNestedMessage.getInputStream()));
} else {
MimeMultipart mimeMultipart = (MimeMultipart) part.getContent();
body = new String(IOUtils.toByteArray(mimeMultipart.getBodyPart(0).getInputStream()));
}
}
}
}
System.out.println(body);
System.out.println(attacments.size());
}
您还可以获取文件的mime类型。
private static void addAttachment(List<FileData> attachments, MimeBodyPart part) throws Exception {
String fileName = part.getFileName();
FileData fileData = new FileData()
.setName(fileName)
.setData(part.getInputStream().readAllBytes())
.setType(getMimeType(fileName));
attachments.add(fileData);
}
private static void addInlineAttachment(List<FileData> attachments, byte[] data, String fileName) throws Exception {
FileData fileData = new FileData()
.setName(fileName)
.setData(data)
.setType(getMimeType(fileName));
attachments.add(fileData);
}
private static String getMimeType(String fileName) throws Exception {
Path path = new File(fileName).toPath();
return Files.probeContentType(path);
}
还有FileData类:
@Data
@Accessors(chain = true)
public class FileData {
byte[] data;
String name;
String type;
}