用JAVA发送邮件,正文乱码该如何解决
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用JAVA发送邮件,正文乱码该如何解决相关的知识,希望对你有一定的参考价值。
如题,我使用了
contentPart.setContent(txt, "text/plain;charset=UTF-8");
contentPart.setText(txt);
multipart.addBodyPart(contentPart);
但是不好用,发出邮件后,控制台还是提示
Content-Type: text/plain; charset=MS932
Content-Transfer-Encoding: base64
求大神!!求解!!
message.setSubject("测试邮件");// 设置邮件的内容体
message.setContent("这里是正文区域", "text/html;charset=UTF-8");// 发送邮件
Transport.send(message);
System.out.println("发送成功");
在后面的2个参数设置一下就好了,一般使用utf-8 参考技术A String bianma = "中国";
String jiema = URLEncoder.encode("中国");
String jieshou = URLDecoder.decode(jiema);
System.out.println("编码后的值:" + jiema);
System.out.println("解码后的值:" + jieshou);追问
这个……是解析成什么编码了?我们要求的编码格式是UTF-8的……
追答String bianma = "中国";
String jiema = URLEncoder.encode("中国","UTF-8");
String jieshou = URLDecoder.decode(jiema,"UTF-8");
System.out.println("编码后的值:" + jiema);
System.out.println("解码后的值:" + jieshou);
额……这样的话,接收到的岂不都是编码了……解码后在发送,收到的东西还是一样的啊,一大长串的问号啊
追答哎吆喂,提问者:
邮箱接收估计应该是GBK国际编码。
而你编程GBK国际编码,那么邮箱接收的也是GBK国际编码。
这样就不会产生乱码了。哎吆喂、、
额,大神啊,我是新手,望指导啊,我把关键代码贴出来,帮看看吧
// 加载标题
message.setSubject(subject);
Multipart multipart = new MimeMultipart();
BodyPart contentPart = new MimeBodyPart();
contentPart.setContent(txt, "text/plain;charset=UTF-8"); //就是这里……不好用啊
contentPart.setText(txt);
multipart.addBodyPart(contentPart);
我现在最大的问题就是不知道怎么转换编码格式~……求解,求大神啊~!!!
参考技术D 我们是使用freemaker编写邮件模版,然后程序中解析模版发出,没有问题。springboot:java实现邮件及附件发送HTML正文的三种方式附带源码
0. 引言
邮件发送是我们日常开发中比较常见的功能,常用于预警信息提醒、统计数据定期发送等需求。一般该方法会由前人封装好,实际开发时只需要调用即可,但具体怎么实现的,如何从零实现邮件发送,这是我们要掌握的。
之前我们讲解了基于javax.mail
和org.apache.commons.mail
实现邮件发送, 今天继续讲解第三种方式基于spring-boot-starter-mail
实现。
- 基于javax.mail实现邮件发送
- 基于commons.mail实现邮件发送
1. 环境准备
1.1 开发环境
以下演示基于当前项目使用的springboot版本,jdk基于1.8版本
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
1.2 开启邮箱协议与授权
其次我们需要了解的是,程序要发送邮件,是需要一个邮箱账号的, 并且其账号需要开启SMTP邮件协议以及邮件授权码,并不是密码。
以下我们以QQ邮箱为例,示范其开启过程,其他邮箱大同小异。
1、登陆邮箱,点击设置
,进入账户
,下拉页面
2、找到POP3/IMAP/SMTP
服务设置。这里我们可以开启POP3/SMTP
或者IMAP/SMTP
服务,两者的区别
3、点击开启
后,会要求你发送短信验证
4、发送后,点击我已发送
,然后会给你一个授权码,将该码保存下来,这就是我们需要的授权码。
5、其次我们需要获取到邮件服务器的smtp地址,比如我们这里用的是qq邮箱,其地址就是smtp.qq.com
。对应类型邮箱的smtp地址直接百度即可。
1.3 常见的邮箱服务及端口
服务商 | smtp服务地址 | smtp服务端口 | pop3服务地址 | pop3服务端口 |
新浪 sina.com | smtp.sina.com.cn | 25 | pop3.sina.com.cn | 110 |
搜狐 sohu.com | smtp.sohu.com | 25 | pop3.sohu.com | 110 |
163 163.com | smtp.163.com | 25 | pop3.163.com | 110 |
QQ qq.com | smtp.qq.com | 25 | pop3.qq.com | 110 |
foxmail foxmail.com | smtp.foxmail.com | 25 | pop3.foxmail.com | 110 |
QQ企业邮箱 exmail.qq.com | smtp.exmail.qq.com | 995 | pop3.exmail.qq.com | 587/465 |
2. 实现
2.1 spring-boot-starter-mail实现
2.1.1 思路
1、我们观察spring-boot-starter-mail
依赖包,发现其实内部使用jakarta.mail
来实现
而jakarta
内部其实也有javax.mail
的包。所以后续我们会发现很多用法与javax.mail
类似
2.1.2 实操
1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
2、修改配置文件application.yml
中
spring:
# spring-boot-starter-mail配置项
mail:
host: smtp.qq.com
username: xxx@qq.com
password: xxx
default-encoding: UTF-8
properties.mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory
# 打印邮件发送过程,生产环境关闭
properties.mail.debug: true
3、创建工具类,实现发送功能(注意这里已经将工具类声明为bean了,所以我们使用时要用依赖注入的形式调用)
/**
* @author benjamin_5
* @Description spring-boot-starter-mail邮件工具类
* @date 2022/10/5
*/
@Component
@AllArgsConstructor
public class EmailSpringUtil
private final JavaMailSender javaMailSender;
private final MailProperties mailProperties;
/**
* 邮件发送
* @param subject 邮件主题
* @param content 邮件内容
* @param contentIsHtml 内容是否为html格式
* @param fromMailPersonalName 发件人昵称
* @param toMail 收件人邮箱
* @param ccMail 抄送人邮箱
* @param bccMail 秘密抄送人邮箱
* @param fileNames 文件名(本地路径)
* @throws GeneralSecurityException
* @throws UnsupportedEncodingException
* @throws MessagingException
*/
public void sendEmail(String subject, String content,boolean contentIsHtml, String fromMailPersonalName,
String toMail, String ccMail, String bccMail, List<String> fileNames) throws MessagingException, UnsupportedEncodingException
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,true);
helper.setFrom(mailProperties.getUsername(),fromMailPersonalName);
helper.setTo(toMail);
if(!ObjectUtils.isEmpty(ccMail))
helper.setCc(ccMail);
if(!ObjectUtils.isEmpty(bccMail))
helper.setBcc(bccMail);
helper.setSubject(subject);
helper.setText(content,contentIsHtml);
// 设置附件(注意这里的fileName必须是服务器本地文件名,不能是远程文件链接)
if(!CollectionUtils.isEmpty(fileNames))
for (String fileName : fileNames)
FileDataSource fileDataSource = new FileDataSource(fileName);
helper.addAttachment(fileDataSource.getName(),fileDataSource);
javaMailSender.send(message);
4、调用测试,我们创建一个接口来模拟测试
@RestController
@AllArgsConstructor
public class EmailController
private final EmailSpringUtil emailSpringUtil;
@GetMapping("sendSpringEmail")
public void sendSpringEmail()
String subject = "这是一个测试标题";
String html = "<h1>统计数据如下所示:</h1>" +
"<table border=\\"1\\">\\n" +
" <tr>\\n" +
" <th>月度销售额</th>\\n" +
" <th>年度销售额</th>\\n" +
" </tr>\\n" +
" <tr>\\n" +
" <td>10000</td>\\n" +
" <td>2000000</td>\\n" +
" </tr>\\n" +
"</table>";
String toMail = "wuhanxue5@sina.com";
String ccMail = "wuhanxue5@163.com";
String fileName = "/Users/wuhanxue/Downloads/供应商接口参数.xlsx";
try
emailSpringUtil.sendEmail(subject,html,true,"邮件提醒系统",toMail,ccMail,null, Arrays.asList(fileName));
catch (MessagingException e)
e.printStackTrace();
catch (UnsupportedEncodingException e)
e.printStackTrace();
4、浏览器访问该接口http://localhost:8080/sendSpringEmail
邮件接收成功,附件和HTML正文也显示正常
查看抄送邮箱,接收正常
补充问题
如果出现接收到的附件为.bin
格式,这是因为附件名称过长导致,mime.mail中的参数splitlongparameters
默认为
true,当附件名过长时,他会自动截取,就会导致我们接收到的附件格式变成.bin
形式的。
要解决该问题就需要将其设置为false。于是我们创建一个启动执行类来单独设置
@Configuration
public class EmailToLongConfig
@PostConstruct
private void init()
// 解决邮件附件名称太长会自动截取,导致附件变成.bin格式问题
System.setProperty("mail.mime.splitlongparameters","false");
当然我们也可以将System.setProperty("mail.mime.splitlongparameters","false");
放到邮件发送的方法中去。
当然如果需求允许,也可以设置一个短一点的附件名来规避该问题
源码地址
以上演示的源码可以在如下地址中下载
总结
从代码可以看出spring-boot-starter-mail
与javax.mail
的实现类似,都是通过MimeMessageHelper
类实现的
至此我们已经讲解完三种实现邮件发送的方法了,实际上邮件发送功能实现非常简单,毕竟我们只是在前人做好的组件上开发,已经站在了巨人的肩膀上。之前演示的代码大家也可以直接应用到生产中,但一定不要盲目的复制粘贴,理解,自己一行一行的复写一遍代码,这是千万不能省的!
以上是关于用JAVA发送邮件,正文乱码该如何解决的主要内容,如果未能解决你的问题,请参考以下文章
使用 javamail api 发送的 html 电子邮件正文在 Outlook 中出现乱码
springboot:java实现邮件及附件发送HTML正文的三种方式附带源码
springboot:java实现邮件及附件发送HTML正文的三种方式附带源码