commons-email 1.5
javax.mail 1.4.7
spring-boot-starter-mail 跟随springboot版本,文中演示的是2.3.7.RELEASE设置,进入账户,下拉页面
2、找到POP3/IMAP/SMTP服务设置。这里我们可以开启POP3/SMTP或者IMAP/SMTP服务,两者的区别
3、点击开启后,会要求你发送短信验证
4、发送后,点击我已发送,然后会给你一个授权码,将该码保存下来,这就是我们需要的授权码。
5、其次我们需要获取到邮件服务器的smtp地址,比如我们这里用的是qq邮箱,其地址就是smtp.qq.com。对应类型邮箱的smtp地址直接百度即可。| 服务商 | 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 |
Properties对象,用于声明smtp相关配置2、重写一个Authenticator,用于声明发件人邮箱地址和授权码3、基于上述两步创建的对象,创建一个Session4、利用session创建一个MimeMessage对象,再利用MimeMessage创建一个MimeMessageHelper对象,该对象用于设置收件人、发件人、抄送、秘密抄送、主题、内容、附件、发送时间等属性5、利用Transport.send方法发送邮件在清楚了实现流程后,我们直接上代码演示<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>/**
* @author benjamin_5
* @Description
* @date 2022/10/3
*/
public class EmailJavaxUtil {
private static final Logger logger = LoggerFactory.getLogger(EmailJavaxUtil.class);
// 发件人smtp邮箱服务地址
private static final String senderSmtpHost = "smtp.qq.com";
// 发件人邮箱地址
private static final String senderEmail = "xxx@qq.com";
// smtp邮箱授权码
private static final String senderPassword = "xxx";
// 端口
private static final String senderSmtpPort = "465";
private static void sendEmail(String subject, String content,boolean contentIsHtml, String fromMailPersonalName,
String toMail, String ccMail, String bccMail, List<String> fileNames)
throws GeneralSecurityException, UnsupportedEncodingException, MessagingException {
// 设置参数
Properties properties = System.getProperties();
// smtp服务地址
properties.put("mail.smtp.host",senderSmtpHost);
// smtp服务端口
properties.put("mail.smtp.port", senderSmtpPort);
// 开启验证
properties.put("mail.smtp.auth","true");
// 开启TLS加密
properties.put("mail.smtp.starttls.enable","true");
// 是否启用socketFactory,默认为true
properties.put("mail.smtp.socketFactory.fallback", "true");
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.ssl.socketFactory", sf);
// 建立会话,利用内部类将邮箱授权给jvm
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(senderEmail, senderPassword);
}
});
// 设置为true可以在控制台打印发送过程,生产环境关闭
session.setDebug(true);
// 创建邮件对象
MimeMessage message = new MimeMessage(session);
// 通过MimeMessageHelper设置正文和附件,否则会导致两者显示不全
MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");
//设置收件人,to为收件人,cc为抄送,bcc为密送
if (StringUtils.isEmpty(toMail)) {
logger.error("邮件收件人为空");
return;
}
//设置发件人
helper.setFrom(new InternetAddress(senderEmail, fromMailPersonalName));
helper.setTo(InternetAddress.parse(toMail, false));
if (!StringUtils.isEmpty(ccMail)) {
helper.setCc(InternetAddress.parse(ccMail, false));
}
if (!StringUtils.isEmpty(bccMail)) {
helper.setBcc(InternetAddress.parse(bccMail, false));
}
// 设置邮件主题
helper.setSubject(subject);
//设置邮件正文内容
helper.setText(content,contentIsHtml);
//设置发送的日期
helper.setSentDate(new Date());
// 设置附件(注意这里的fileName必须是服务器本地文件名,不能是远程文件链接)
if(!CollectionUtils.isEmpty(fileNames)){
for (String fileName : fileNames) {
FileDataSource fileDataSource = new FileDataSource(fileName);
helper.addAttachment(fileDataSource.getName(),fileDataSource);
}
}
//调用Transport的send方法去发送邮件
Transport.send(message);
}
}public static void main(String[] args) throws MessagingException, GeneralSecurityException, UnsupportedEncodingException {
String fileName = "/Library/project/study/java/mail_send_demo/src/main/resources/供应商接口参数.xlsx";
sendEmail("测试邮件1","这是一封测试邮件",false,"55555","wuhanxue5@sina.com",null,null, Collections.singletonList(fileName));
}
//设置邮件正文内容
message.setText(content);
if(!CollectionUtils.isEmpty(fileNames)){
// 附件上传组件
Multipart multipart =new MimeMultipart("mixed");
for (String fileName : fileNames) {
MimeBodyPart bodyPart = new MimeBodyPart();
FileDataSource fileDataSource = new FileDataSource(fileName);
bodyPart.setDataHandler(new DataHandler(fileDataSource));
// 解决附件中文名乱码
bodyPart.setFileName(MimeUtility.encodeText(fileDataSource.getName(), "utf-8", null));
// 添加附件
multipart.addBodyPart(bodyPart);
}
// 附件的设置语句必须放在设置正文内容之后,否则会导致附件设置为空
message.setContent(multipart);
}
解决的办法就是使用MimeMessageHelper类来实现,如上述演示所示。2、附件上传有多种方式,除了上述演示的使用FileDataSource形式添加附件外,还有文件、输入流的方式来添加,可以结合需求多样开发。addAttachment(String attachmentFilename, DataSource dataSource)addAttachment(String attachmentFilename, File file)addAttachment(String attachmentFilename, InputStreamSource inputStreamSource)addAttachment(String attachmentFilename, InputStreamSource inputStreamSource, String contentType)addAttachment方法外,addInline方法也能添加附件。生产开发复制粘贴上述的工具类完全足够,但是要想进一步理解,深入掌握组件,更需要大家去阅读源码,了解api方法的多样性。contentIsHtml参数,用来标识内容是否为html其实现利用了MimeMessageHelper提供的setText方法的第二参数,通过调用setHtmlTextToMimePart或setPlainTextToMimePart来实现html正文的解析
话不多说,我们来测试一下public static void main(String[] args) throws MessagingException, GeneralSecurityException, UnsupportedEncodingException {
String fileName = "/Library/project/study/java/mail_send_demo/src/main/resources/供应商接口参数.xlsx";
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>";
sendEmail("统计数据",html,true,"55555","wuhanxue5@sina.com",null,null, Collections.singletonList(fileName));
}
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参
我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送