项目上有个需求:定时给一些人发邮件,邮件中需要带个附件,因为不想在服务器端生成附件,所以就采用了文件流的形式,但初步尝试后发现 大部分Android 手机带的邮件客户端能收到邮件,也能打开附件,但 iPhone 自带的“邮件”APP,只能看到附件标志(一个曲别针),但看不到任何附件。
一、问题现象
iPhone 自带 邮件APP,收到 的邮件,只能看到有个附件,但是找不到附件,如下图:
二、问题解决方法
1. 使用邮箱自带的专业 APP,如网易、新浪、等等就能看到。
2. 换手机
3. 改代码
本文使用第 3 种解决问题的思路
三、核心代码
1. 整体技术
使用org.springframework.mail.javamail.JavaMailSenderImpl
2. 代码
public class TESTNoticeTask{
private String serverDir = "";
private String serverUrl = ”“;
private String serverTmpDir = ”“;
private String MAIL_SMTP_SERVER = ”“;
private String MAIL_SENDER = ”“;
private String MAIL_SENDER_PWS = ”“;
private String MAIL_PORT = ”“;
private void toSendMailWithExcel(){//就是这里发送
sendMsgFileDsV2("收件人接收者Email","CC抄送人Email","邮件主题","邮件内容","附件.xls",makeExcel());
}
public void sendMsgFileDsV2(String to, String cc, String title,
String text,String affixName,
ByteArrayInputStream inputstream) {//这一段程序在网上抄的,稍加改造了一下
try {
// 创建邮件发送类
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setSession(assembleSession());
// 创建邮件信息类
MimeMessage msg = javaMailSender.createMimeMessage();
// 创建MimeMessageHelper对象,MimeMessage的辅助类
MimeMessageHelper message = new MimeMessageHelper(msg, true);
message.setFrom(new InternetAddress(MAIL_SENDER));
message.setSubject(title);
// 要发送的Email账号
message.setTo(to);
// 要抄送的Email账号
if(cc != null) {
message.setCc(cc);
}
// 标题
message.setSubject(title);
// 邮件主体
message.setText(text);
ByteArrayDataSource file = new ByteArrayDataSource(inputstream, "application/vnd.ms-excel;charset=UTF-8");
// 附件 关键部分
message.addAttachment(MimeUtility.encodeWord(affixName,"utf-8","B"),file);
javaMailSender.send(msg);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("邮件发送失败!" + e);
}
}
public Session assembleSession() {
Session session = null;
Properties props = new Properties();
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.port", MAIL_PORT);
props.setProperty("mail.smtp.host", MAIL_SMTP_SERVER);//邮件服务器
props.setProperty("mail.smtp.ssl.protocols","TLSv1.2");
//开启安全协议
MailSSLSocketFactory sf = null;
try {
//sf = new MailSSLSocketFactory();
//使用TLS v1.2版本
sf = new MailSSLSocketFactory("TLSv1.2");
sf.setTrustAllHosts(true);
} catch (GeneralSecurityException e1) {
e1.printStackTrace();
}
props.put("mail.smtp.ssl.socketFactory", sf);
props.put("mail.smtp.ssl.enable", "true");
session = Session.getDefaultInstance(props, new MyAuthenricator(MAIL_SENDER, MAIL_SENDER_PWS));
return session;
}
//用户名密码验证,需要实现抽象类Authenticator的抽象方法PasswordAuthentication
static class MyAuthenricator extends Authenticator {
String u = null;
String p = null;
public MyAuthenricator(String u, String p) {
this.u = u;
this.p = p;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(u, p);
}
}
private ByteArrayInputStream makeExcel(){
ByteArrayInputStream iss = null;
try {
List<XXXX> listObj = 省略;
String[] headers = {"序号", "CreateDate", "姓名"};
// 声明一个工作薄
HSSFWorkbook wb = new HSSFWorkbook();
// 生成一个表格
HSSFSheet sheet = wb.createSheet();
HSSFFont fontStyle = wb.createFont();
fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
cellStyle.setFont(fontStyle);
HSSFRow row = sheet.createRow(0);
//第 0 行, 标题
row = sheet.createRow(0);
HSSFCell cell0 = row.createCell(0);
cell0.setCellValue("统计)");
sheet.addMergedRegion(new CellRangeAddress(0,0,0,(headers.length-1)));
cell0.setCellStyle(cellStyle);
//第 1 行 //副标题,写人数
row = sheet.createRow(1);
HSSFCell cell00 = row.createCell(0);
cell00.setCellValue("总共: 人");
sheet.addMergedRegion(new CellRangeAddress(1,1,0,(headers.length-1)));
cell00.setCellStyle(cellStyle);
//第 2 行,表头
row = sheet.createRow(2);
for (int i = 0; i < headers.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(headers[i]);
}
int rowIndex = 3;
for (int j = 0; j < listObj.size(); j++) {
XXXX xxx = listObj.get(j);
row = sheet.createRow(rowIndex);
rowIndex++;
HSSFCell cell1 = row.createCell(0);
cell1.setCellValue(j+1);
cell1 = row.createCell(1);
cell1.setCellValue(sdf1.format(xxx.getCreateDate()));
cell1 = row.createCell(2);
cell1.setCellValue(xxx.getUserName());
}
for (int i = 0; i < headers.length; i++) {
sheet.autoSizeColumn(i);
}
ByteArrayOutputStream os = new ByteArrayOutputStream(1000);
wb.write(os);
wb.close();
iss = new ByteArrayInputStream(os.toByteArray());
os.close();
}catch(Exception e){
e.printStackTrace();
}
return iss;
}
}