问题:
客户生产机器,每次发送邮件带有附件的时候就会导致乱码,而且乱码很奇特,有规律的那种样例就是:
=?UTF-8?Q?=E6=96=B0=E5=BB=BA=E6=96=87=E6=9C=AC=E6=96=87=E6=A1=A3_?= =?UTF-8?Q?=5F2=29=2Etxt?=
但是我的真实的文件名称是“新建文本文件.txt”
百度各种办法,有个说没有编码。有的说系统语言有问题
无效办法一:
public static void main(String[] args) { String s = "=?UTF-8?Q?=E6=96=B0=E5=BB=BA=E6=96=87=E6=9C=AC=E6=96=87=E6=A1=A3_?= =?UTF-8?Q?=5F2=29=2Etxt?="; try{ Map<String, String> fileMap = new HashMap<>(); fileMap.put("文本文件.txt","/opt/uuu"); MailBean mailBean = new MailBean(); mailBean.setAttachments(fileMap); UnitedLogger.debug(mailBean.getAttachments()); System.out.println(s); System.out.println("编码后的文件名称encodeWord:"+ MimeUtility.encodeWord(s)); System.out.println("编码后的文件名称encodeWord-B:"+ MimeUtility.encodeWord(s,"UTF8","B")); System.out.println("编码后的文件名称encodeText:"+ MimeUtility.encodeText(s)); System.out.println("编码后的文件名称encodeText-B:"+ MimeUtility.encodeText(s,"UTF8","B")); System.out.println("编码后的文件名称encodeText-B:"+ MimeUtility.encodeText(s,MimeUtility.mimeCharset("gb2312"), null)); }catch (Exception e){ } }
上述办法无法解决,还是乱码
无效办法二:
因为客户生产是Redhat系统,所以我就查看了一下他们的服务器语言变量
echo $LANG
发现打印的是US的语言,我就经过对方同意后改了一下这个变量,还是不行
export LANG="zh_CN.UTF-8" export LC_ALL="zh_CN.UTF-8"
在中午吃外卖的时候,碰到产品组一个同事,随口问了一句,然后回到工位他给我发了个链接:
https://blog.csdn.net/qq_29407009/article/details/78557886
这个解决了我的问题:
解决办法就是不让截断文件名。因为中文文件名被base64加密后肯定超过60位长度:
System.setProperty("mail.mime.splitlongparameters","false");
然而,测试环境正常,生产环境又不行了,后来想是不是docker环境不支持中文导致的
生产解决办法:
1)进入docker镜像
docker exec -it id bash
2)查看语言
locale
POSIX是不支持中文的
3)查看系统是否有中文包:
locale -a
如果有C.UTF-8或者zh_CN.UTF-8
4)执行
LANG=C.UTF-8
如果没有C.UTF-8或者zh_CN.UTF-8
就需要
yum install kde-l10n-Chinese -y
yum reinstall glibc-common -y
localedef -c -f UTF-8 -i zh_CN zh_CN.utf8
最后附上我的邮件发送代码:
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.datadriver.common.entity.RunnableAsyc; import com.datadriver.common.entity.UnitedException; import com.datadriver.common.entity.UnitedLogger; import com.datadriver.common.util.ThreadPoolExecutorUtil; import com.datadriver.email.model.MailBean; import com.datadriver.email.service.EmailSettingInfoService; import org.apache.commons.lang3.StringUtils; import org.springframework.core.io.FileSystemResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import javax.annotation.Resource; import javax.mail.Authenticator; import javax.mail.MessagingException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeUtility; import java.io.File; import java.util.*; import java.util.Map.Entry; import java.util.concurrent.ExecutionException; @Component public class GFXDMailSenderExecutor { private EmailSettingInfoService emailSettingInfoService; private JavaMailSenderImpl javaMailSender; private static final String TRUE = "true"; private static final String SEND_TYPE_TEXT = "text"; private static final String SEND_TYPE_HTML = "html"; private static final String SEND_STATUS_FAILD = "101"; private static final String SEND_STATUS_SUCCESS = "100"; public GFXDMailSenderExecutor() { } public void initMailSetting() { boolean empty = ObjectUtils.isEmpty(this.javaMailSender); boolean notEmpty = !ObjectUtils.isEmpty(this.javaMailSender); boolean fieldEmpty = notEmpty && (StringUtils.isBlank(this.javaMailSender.getUsername()) || StringUtils.isBlank(this.javaMailSender.getPassword())); if (empty || fieldEmpty) { this.javaMailSender = this.javaMailSender(); } } public void senderEmail(MailBean mailBean) { this.submit(mailBean); } private void submit(MailBean m) { try { ThreadPoolExecutorUtil.submit(new GFXDMailSenderExecutor.SendMailThread(m, this.emailSettingInfoService)); } catch (ExecutionException | InterruptedException var3) { UnitedLogger.error("MailSenderExecutor.submit******* 邮件异常 ID=" + m.getRecordId() + "Error:", var3); Thread.currentThread().interrupt(); } } private void send(MailBean mailBean) throws Exception { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(this.javaMailSender.getUsername()); String[] emails = getEmails(mailBean.getRecipientsEmail()); message.setTo(emails); message.setSubject(mailBean.getSubject()); message.setText(mailBean.getContent()); message.setSentDate(new Date()); UnitedLogger.info("线程运行正在发送至 " + mailBean.getRecipientsEmail() + " ....\n"); this.javaMailSender.send(message); } private void sendHtml(MailBean mailBean) throws Exception { UnitedLogger.debug("getAttachments:"+mailBean.getAttachments()); MimeMessage message = this.javaMailSender.createMimeMessage(); MimeMessageHelper messageHelper; try { messageHelper = new MimeMessageHelper(message, true, "UTF-8"); } catch (MessagingException var11) { throw new UnitedException("I18N-MSG-999900000230"); } messageHelper.setFrom(this.javaMailSender.getUsername()); String[] emails = getEmails(mailBean.getRecipientsEmail()); messageHelper.setTo(emails); if (org.apache.commons.lang3.ObjectUtils.anyNotNull(new Object[]{mailBean.getSubject()})) { messageHelper.setSubject(mailBean.getSubject()); } messageHelper.setText(mailBean.getContent(), true); Iterator it; Entry entry; String cid; String filePath; File file; FileSystemResource fileResource; if (org.apache.commons.lang3.ObjectUtils.anyNotNull(new Object[]{mailBean.getPictures()})) { it = mailBean.getPictures().entrySet().iterator(); while(it.hasNext()) { entry = (Entry)it.next(); cid = (String)entry.getKey(); filePath = (String)entry.getValue(); if (StringUtils.isBlank(cid) || StringUtils.isBlank(filePath)) { UnitedLogger.debug("请确认每张图片的ID和图片地址是否齐全\n"); throw new UnitedException("I18N-MSG-999900000240"); } file = new File(filePath); if (!file.exists()) { UnitedLogger.debug("图片路径[" + filePath + "]不存在\n"); throw new UnitedException("I18N-MSG-999900000250"); } fileResource = new FileSystemResource(file); messageHelper.addInline(cid, fileResource); } } if (org.apache.commons.lang3.ObjectUtils.anyNotNull(new Object[]{mailBean.getAttachments()})) { it = mailBean.getAttachments().entrySet().iterator(); UnitedLogger.debug("getAttachments:"+mailBean.getAttachments()); while(it.hasNext()) { entry = (Entry)it.next(); cid = (String)entry.getKey(); filePath = (String)entry.getValue(); if (StringUtils.isBlank(cid) || StringUtils.isBlank(filePath)) { UnitedLogger.debug("请确认每个附件的ID和地址是否齐全\n"); throw new UnitedException("I18N-MSG-999900000260"); } file = new File(filePath); if (!file.exists()) { UnitedLogger.debug("附件路径[" + filePath + "]不存在\n"); throw new UnitedException("I18N-MSG-999900000270"); } fileResource = new FileSystemResource(file); messageHelper.addAttachment(cid, fileResource); } } messageHelper.setSentDate(new Date()); UnitedLogger.info("线程运行正在发送至 " + mailBean.getRecipientsEmail() + " ....\n"); this.javaMailSender.send(message); } private static String[] getEmails(String emailstr) throws UnitedException { String[] toEmailArray = null; if (StringUtils.isNotBlank(emailstr)) { toEmailArray = emailstr.split(","); List<String> toEmailList = new ArrayList(); if (!org.apache.commons.lang3.ObjectUtils.anyNotNull(toEmailArray)) { UnitedLogger.debug("收件人邮箱不得为空\n"); throw new UnitedException("I18N-MSG-999900000280"); } String[] var3 = toEmailArray; int var4 = toEmailArray.length; for(int var5 = 0; var5 < var4; ++var5) { String s = var3[var5]; if (StringUtils.isNotBlank(s)) { toEmailList.add(s); } } if (!org.apache.commons.lang3.ObjectUtils.anyNotNull(new Object[]{toEmailList})) { UnitedLogger.debug("收件人邮箱不得为空\n"); throw new UnitedException("I18N-MSG-999900000280"); } toEmailArray = new String[toEmailList.size()]; if (org.apache.commons.lang3.ObjectUtils.anyNotNull(new Object[]{toEmailList})) { for(int i = 0; i < toEmailList.size(); ++i) { toEmailArray[i] = (String)toEmailList.get(i); } } } return toEmailArray; } private JavaMailSenderImpl javaMailSender() { JavaMailSenderImpl sender = new JavaMailSenderImpl(); try { System.setProperty("mail.mime.splitlongparameters","false"); String jsonstr = this.emailSettingInfoService.getEmailSettingInfo(); if (StringUtils.isNotBlank(jsonstr)) { JSONObject json = JSON.parseObject(jsonstr); String host = (String)json.get("host"); Integer port = Integer.parseInt((String)json.get("port")); final String emailname = (String)json.get("username"); final String password = (String)json.get("password"); String protocol = (String)json.get("protocol"); String auth = (String)json.get("auth"); String starttls = (String)json.get("starttls"); String ssl = (String)json.get("ssl"); sender.setHost(host); sender.setPort(port); sender.setProtocol(protocol); sender.setUsername(emailname); sender.setPassword(password); sender.setDefaultEncoding("UTF-8"); Properties props = new Properties(); props.setProperty("mail.smtp.auth", auth); if (StringUtils.equals("true", ssl)) { props.setProperty("mail.smtp.ssl.enable", ssl); props.setProperty("mail.smtp.ssl.trust", host); props.setProperty("mail.smtp.socketFactory.port", String.valueOf(port)); props.setProperty("mail.smtp.socketFactory.fallback", "false"); props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); } if (StringUtils.equals("true", starttls)) { props.setProperty("mail.smtp.starttls.enable", starttls); props.setProperty("mail.smtp.starttls.required", starttls); } props.setProperty("mail.transport.protocol", protocol); Session session = Session.getDefaultInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(emailname, password); } }); sender.setSession(session); sender.setJavaMailProperties(props); } } catch (UnitedException var14) { UnitedLogger.error(var14); } return sender; } private EmailSettingInfoService getEmailSettingInfoService() { return this.emailSettingInfoService; } @Resource( name = "emailSettingInfoService" ) private void setEmailSettingInfoService(EmailSettingInfoService emailSettingInfoService) { this.emailSettingInfoService = emailSettingInfoService; } private class SendMailThread extends RunnableAsyc { private MailBean mailBean; private EmailSettingInfoService emailSettingInfoService; public void run() { String status = "101"; try { UnitedLogger.info("------------ 线程运行正在发送 ----------\n"); if ("text".equals(this.mailBean.getSendType())) { GFXDMailSenderExecutor.this.send(this.mailBean); } else if ("html".equals(this.mailBean.getSendType())) { GFXDMailSenderExecutor.this.sendHtml(this.mailBean); } UnitedLogger.info("------------ 发送邮件至 " + this.mailBean.getRecipientsEmail() + " 完成 ----------\n"); status = "100"; } catch (Exception var3) { UnitedLogger.error(var3); status = "101"; } if (StringUtils.isNotBlank(this.mailBean.getRecordId())) { this.emailSettingInfoService.updateMessageRecordStatusById(status, this.mailBean.getRecordId()); } } public SendMailThread(MailBean mailBean, EmailSettingInfoService emailSettingInfoService) { this.mailBean = mailBean; this.emailSettingInfoService = emailSettingInfoService; } } }
2、MailBean
import java.util.Map; public class MailBean { private String recipientsEmail; private String subject; private String content; private String recordId; private String sendType = "html"; private Map<String, Object> params; private Map<String, String> pictures; private Map<String, String> attachments; private String sendStatus; public MailBean() { } public MailBean(String recipientsEmail, String subject, String content) { this.recipientsEmail = recipientsEmail; this.subject = subject; this.content = content; } public MailBean(String recipientsEmail, String subject, String content, String recordId) { this.recipientsEmail = recipientsEmail; this.subject = subject; this.content = content; this.recordId = recordId; } public MailBean(String recipientsEmail, String subject, String content, String recordId, String sendType) { this.recipientsEmail = recipientsEmail; this.subject = subject; this.content = content; this.recordId = recordId; this.sendType = sendType; } public MailBean(String recipientsEmail, String subject, String content, String recordId, Map<String, String> pictures, Map<String, String> attachments) { this.recipientsEmail = recipientsEmail; this.subject = subject; this.content = content; this.recordId = recordId; this.pictures = pictures; this.attachments = attachments; } public MailBean(String recipientsEmail, String subject, String content, String recordId, String sendType, Map<String, String> pictures, Map<String, String> attachments) { this.recipientsEmail = recipientsEmail; this.subject = subject; this.content = content; this.recordId = recordId; this.sendType = sendType; this.pictures = pictures; this.attachments = attachments; } public MailBean(String recipientsEmail, String subject, String content, String recordId, String sendType, Map<String, String> pictures, Map<String, String> attachments, Map<String, Object> params) { this.recipientsEmail = recipientsEmail; this.subject = subject; this.content = content; this.recordId = recordId; this.sendType = sendType; this.pictures = pictures; this.attachments = attachments; this.params = params; } public String getRecipientsEmail() { return this.recipientsEmail; } public void setRecipientsEmail(String recipientsEmail) { this.recipientsEmail = recipientsEmail; } public String getSubject() { return this.subject; } public void setSubject(String subject) { this.subject = subject; } public String getContent() { return this.content; } public void setContent(String content) { this.content = content; } public String getRecordId() { return this.recordId; } public void setRecordId(String recordId) { this.recordId = recordId; } public String getSendType() { return this.sendType; } public void setSendType(String sendType) { this.sendType = sendType; } public Map<String, Object> getParams() { return this.params; } public void setParams(Map<String, Object> params) { this.params = params; } public Map<String, String> getPictures() { return this.pictures; } public void setPictures(Map<String, String> pictures) { this.pictures = pictures; } public Map<String, String> getAttachments() { return this.attachments; } public void setAttachments(Map<String, String> attachments) { this.attachments = attachments; } public String getSendStatus() { return this.sendStatus; } public void setSendStatus(String sendStatus) { this.sendStatus = sendStatus; } }