前言
最近翻出來好久沒有看的kindle,准備繼續我的閱讀之路。當然,也是因為發現了一個非常好的獲取電子書資源的網站,又燃起了我的閱讀興趣。
然而,往kindle里傳輸電子書的方式一共有四種:
- 直接在kindle商城購買正版電子書,會同步到kindle上。但是我不買書哦
- 通過連接電腦傳輸。還得連電腦,可真費勁。
- 給你的kindle發郵件,把電子書帶到郵件的附件里,就可以同步到kindle上。這個是很常用的方式,但是郵箱這種東西,就是收垃圾電子郵件的,我這幾年都沒有主動發過郵件了。
- 在你的iOS、Android版本的kindle應用上打開電子書,也會同步到kindle。我要是用了app了我還用kindle干啥?
所以說,亞馬遜這種西方互聯網公司,就缺少鑽研用戶心思的能力(雖然說中國互聯網公司鑽研的有些過分了……)你在官網上整個上傳功能不就好了?這么多年了,我都沒有見到過類似的功能。還在用古老的電子郵件方式來傳輸文件……
誒?那我讓發郵件這件事變得容易一些不就行了?寫個小項目來實現吧!
快速發郵件,都需要哪些准備?
所以,我們的思路就是,通過代碼獲取到要傳輸到kindle的電子書,然后自動發送郵件到kindle的郵箱就好啦。
涉及到的知識點:
- 文件的讀取和操作
- 發郵件
常用的語言是Java,就先用Java簡單實現一下了,以后再用python試試。
知識點一:文件的讀取和操作
我們用File
類來獲取即可。
整個流程如下:
- 指定我們存放電子書的路徑,就以
/Users/xiaobai/Documents/csdn/kindle
路徑為例吧。 - 通過路徑獲取到該文件夾下的文件列表。使用
file.listFiles()
- 格式的校驗(萬一混進去不是電子書的奇怪文件呢)
- 遍歷文件列表,通過發送郵件發送電子書。其中
mailSendService.send
方法在后面會提到 - 將發送成功的電子書移動到已發送文件夾中。使用
file.renameTo(newFile)
方法。這里要先創建好/Users/xiaobai/Documents/csdn/kindle/sent
這個文件夾哦。
話不多說,上代碼:
public void sendKindle() {
// 獲取當前路徑下的全部文件
File currentPathFile = new File("/Users/xiaobai/Documents/csdn/kindle");
List<File> files = Arrays.asList(currentPathFile.listFiles());
// 過濾留下指定格式的文件
if (CollectionUtils.isEmpty(files)) {
log.info("當前路徑下不存在其他的文件");
return;
}
List<File> fileList = files.stream().filter(o -> {
String[] split = o.getName().split("\\.");
return (split.length > 1 && SUFFIX_LIST.contains(split[split.length - 1]));
}).collect(Collectors.toList());
if (CollectionUtils.isEmpty(fileList)) {
log.info("未找到指定類型的文件");
return;
}
for (File file : fileList) {
mailSendService.send("xiaobaibai@kindle.cn", file);
File newFile = new File("/Users/xiaobai/Documents/csdn/kindle/sent/" + file.getName());
file.renameTo(newFile);
}
}
知識點二:發郵件
郵箱后台配置
首先你要准備一個郵箱(這不是廢話么),之后需要開啟郵箱的smtp協議。
以我自己用的163郵箱為例,在設置中開啟這兩項,如圖:
開啟之后,會生成一個授權密碼,需要保存起來,在發送郵件時需要用這個密碼。
依賴引入和配置
至於如何用Java發郵件,我們就直接用Spring Boot提供的郵件組件了。在maven配置中引入spring-boot-starter-mail
依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
或者是在初始化Spring Boot項目時,勾選Java Mail Sender
之后,在application.yml文件中,配置如下信息:
spring:
mail:
host: smtp.163.com
# 不用填寫端口號
port:
# 發送郵件的郵箱地址,這里是個假的地址哈,實現時需要用真實的郵箱地址
username: sendmailtokindle@163.com
# 剛才在郵箱設置后台生成的授權密碼
password: UXXXXXXXXXXXXQ
protocol: smtp
default-encoding: UTF-8
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
mail.smtp.starttls.required: true
mail.smtp.socketFactory.port: 465
mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback: false
寫代碼
做好郵箱的配置,我們就可以寫發送郵件的代碼了。發郵件的模塊如下:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
@Service
public class MailSendService {
@Autowired
private JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String from;
public void send(String to, File file) {
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(file.getName());
helper.setText("自動推送kindle書籍:" + file.getName(), false);
FileSystemResource attachment = new FileSystemResource(file);
helper.addAttachment(attachment.getFilename(), attachment);
} catch (MessagingException e) {
e.printStackTrace();
}
mailSender.send(message);
}
}
這里自動注入的JavaMailSender類就是發送郵件的sdk,我們通過創建一個MimeMessageHelper類,來輔助創建一個可以發送附件的MimeMessage對象。這里要注意,如果沒有設置text的值,在發送郵件時會因為text為null報錯,這是我趟的一個坑。
總結
好啦,最后我們把要發送的電子書放到路徑下,然后執行第一步里的sendKindle()方法,就可以自動把電子書發送到kindle的郵箱了,而且也會將發送過的電子書自動移到已發送的文件夾里備份,防止以后重復發送。
之后要做的,就是准備把這個功能打包成一個應用,做成一個可視化的界面,然后直接拖動電子書到界面里就可以直接發郵件出去。等我再研究研究,下一篇文章見了!