用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.setRecipient(RecipientType.TO, to);// 设置邮件标题
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);

本回答被提问者和网友采纳
参考技术B http://wenku.baidu.com/view/b9ecb72e7375a417866f8fd8.html 参考技术C 注意编码格式的转换追问

我现在最大的问题就是不知道怎么转换编码格式~……求解,求大神啊~!!!

参考技术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、登陆邮箱,点击​​设置​​​,进入​​账户​​,下拉页面

springboot:java实现邮件及附件发送、HTML正文的三种方式(三)【附带源码】_邮件发送

2、找到​​POP3/IMAP/SMTP​​​服务设置。这里我们可以开启​​POP3/SMTP​​​或者​​IMAP/SMTP​​服务,两者的区别

springboot:java实现邮件及附件发送、HTML正文的三种方式(三)【附带源码】_java_02

3、点击​​开启​​后,会要求你发送短信验证

springboot:java实现邮件及附件发送、HTML正文的三种方式(三)【附带源码】_java_03

4、发送后,点击​​我已发送​​,然后会给你一个授权码,将该码保存下来,这就是我们需要的授权码。

springboot:java实现邮件及附件发送、HTML正文的三种方式(三)【附带源码】_邮件发送_04

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​​来实现

springboot:java实现邮件及附件发送、HTML正文的三种方式(三)【附带源码】_java_05

而​​jakarta​​​内部其实也有​​javax.mail​​​的包。所以后续我们会发现很多用法与​​javax.mail​​类似

springboot:java实现邮件及附件发送、HTML正文的三种方式(三)【附带源码】_spring

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正文也显示正常

springboot:java实现邮件及附件发送、HTML正文的三种方式(三)【附带源码】_spring

查看抄送邮箱,接收正常

springboot:java实现邮件及附件发送、HTML正文的三种方式(三)【附带源码】_spring

补充问题

如果出现接收到的附件为​​.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");​​放到邮件发送的方法中去。

当然如果需求允许,也可以设置一个短一点的附件名来规避该问题

源码地址

以上演示的源码可以在如下地址中下载

​git源码地址​

总结

从代码可以看出​​spring-boot-starter-mail​​​与​​javax.mail​​​的实现类似,都是通过​​MimeMessageHelper​​类实现的

至此我们已经讲解完三种实现邮件发送的方法了,实际上邮件发送功能实现非常简单,毕竟我们只是在前人做好的组件上开发,已经站在了巨人的肩膀上。之前演示的代码大家也可以直接应用到生产中,但一定不要盲目的复制粘贴,理解,自己一行一行的复写一遍代码,这是千万不能省的!


以上是关于用JAVA发送邮件,正文乱码该如何解决的主要内容,如果未能解决你的问题,请参考以下文章

我发送的邮件人家怎么看着是乱码??

使用 javamail api 发送的 html 电子邮件正文在 Outlook 中出现乱码

springboot:java实现邮件及附件发送HTML正文的三种方式附带源码

springboot:java实现邮件及附件发送HTML正文的三种方式附带源码

解决java mail发送TXT附件被直接显示在正文中的问题

Java 发送邮件是出现乱码 乱码结果如下: