Câu trả lời:
Không có xử lý ngoại lệ, nhưng đây là:
List<File> attachments = new ArrayList<File>();
for (Message message : temp) {
Multipart multipart = (Multipart) message.getContent();
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()) &&
StringUtils.isBlank(bodyPart.getFileName())) {
continue; // dealing with attachments only
}
InputStream is = bodyPart.getInputStream();
// -- EDIT -- SECURITY ISSUE --
// do not do this in production code -- a malicious email can easily contain this filename: "../etc/passwd", or any other path: They can overwrite _ANY_ file on the system that this code has write access to!
// File f = new File("/tmp/" + bodyPart.getFileName());
FileOutputStream fos = new FileOutputStream(f);
byte[] buf = new byte[4096];
int bytesRead;
while((bytesRead = is.read(buf))!=-1) {
fos.write(buf, 0, bytesRead);
}
fos.close();
attachments.add(f);
}
}
Câu hỏi rất cũ, nhưng có lẽ nó sẽ giúp ích cho ai đó. Tôi muốn mở rộng câu trả lời của David Rabinowitz.
if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
không nên trả lại tất cả các bộ phận như bạn mong đợi, bởi vì bạn có thể có thư trong đó phần hỗn hợp không có sự sắp xếp xác định.
----boundary_328630_1e15ac03-e817-4763-af99-d4b23cfdb600
Content-Type: application/octet-stream;
name="00000000009661222736_236225959_20130731-7.txt"
Content-Transfer-Encoding: base64
vì vậy trong trường hợp này, bạn cũng có thể kiểm tra tên tệp. Như thế này:
if (!Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) && StringUtils.isBlank(part.getFileName())) {...}
BIÊN TẬP
có toàn bộ mã làm việc bằng cách sử dụng điều kiện được mô tả ở trên .. Bởi vì mỗi phần có thể đóng gói các phần khác và phần đính kèm nên được lồng vào, đệ quy được sử dụng để xem qua tất cả các phần
public List<InputStream> getAttachments(Message message) throws Exception {
Object content = message.getContent();
if (content instanceof String)
return null;
if (content instanceof Multipart) {
Multipart multipart = (Multipart) content;
List<InputStream> result = new ArrayList<InputStream>();
for (int i = 0; i < multipart.getCount(); i++) {
result.addAll(getAttachments(multipart.getBodyPart(i)));
}
return result;
}
return null;
}
private List<InputStream> getAttachments(BodyPart part) throws Exception {
List<InputStream> result = new ArrayList<InputStream>();
Object content = part.getContent();
if (content instanceof InputStream || content instanceof String) {
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) || StringUtils.isNotBlank(part.getFileName())) {
result.add(part.getInputStream());
return result;
} else {
return new ArrayList<InputStream>();
}
}
if (content instanceof Multipart) {
Multipart multipart = (Multipart) content;
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
result.addAll(getAttachments(bodyPart));
}
}
return result;
}
null
. Đúng không?
Trình tiết kiệm thời gian cho mã nơi bạn lưu tệp đính kèm:
với javax mail phiên bản 1.4 trở lên , bạn có thể nói
// SECURITY LEAK - do not do this! Do not trust the 'getFileName' input. Imagine it is: "../etc/passwd", for example.
// bodyPart.saveFile("/tmp/" + bodyPart.getFileName());
thay vì
InputStream is = bodyPart.getInputStream();
File f = new File("/tmp/" + bodyPart.getFileName());
FileOutputStream fos = new FileOutputStream(f);
byte[] buf = new byte[4096];
int bytesRead;
while((bytesRead = is.read(buf))!=-1) {
fos.write(buf, 0, bytesRead);
}
fos.close();
Bạn chỉ cần sử dụng Apache Commons Mail API MimeMessageParser - getAttachmentList () cùng với Commons IO và Commons Lang.
MimeMessageParser parser = ....
parser.parse();
for(DataSource dataSource : parser.getAttachmentList()) {
if (StringUtils.isNotBlank(dataSource.getName())) {}
//use apache commons IOUtils to save attachments
IOUtils.copy(dataSource.getInputStream(), ..dataSource.getName()...)
} else {
//handle how you would want attachments without file names
//ex. mails within emails have no file name
}
}