本次测试演示带模板的邮件,使用 Freemark 实现邮件的模板。
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
添加配置
在 application.properties 中添加
这里的密码需要设置的是163的第三方工具访问密码
# javamail 配置
spring.mail.host=smtp.163.com
spring.mail.username=13738137546@163.com
spring.mail.password=
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
编码
@Component
@EnableConfigurationProperties(MailProperties.class)
public class JavaMailComponent {
private static final String template = "mail.ftl";
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private MailProperties mailProperties;
public void sendMail(String email) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("email", email);
try {
// 获取内容
String text = this.getTextByTemplate(template, map);
// 发送
this.send(email, text);
} catch (Exception e) {
e.printStackTrace();
}
}
private String getTextByTemplate(String template, Map<String, Object> model) throws Exception {
return FreeMarkerTemplateUtils
.processTemplateIntoString(this.freeMarkerConfigurer.getConfiguration().getTemplate(template), model);
}
private String send(String email, String text) throws MessagingException, UnsupportedEncodingException {
MimeMessage message = this.javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
InternetAddress from = new InternetAddress();
from.setAddress(this.mailProperties.getUsername());
from.setPersonal("崔笑颜", "UTF-8");
helper.setFrom(from);
helper.setTo(email);
helper.setSubject("SpringBoot 发送的第一封邮件");
helper.setText(text, true);
this.javaMailSender.send(message);
return text;
}
}
在 src/main/resources 下的 template 目录下创建名为 mail.ftl 的文件,其内容如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div style="width: 600px; text-align: left; margin: 0 auto;">
<h1 style="color: #005da7;">崔笑颜</h1>
<div style="border-bottom: 5px solid #005da7; height: 2px; width: 100%;"></div>
<div style="border: 1px solid #005da7; font-size: 16px; line-height: 50px; padding: 20px;">
<div>${email},您好!</div>
<div>
这是个测试
</div>
<div>
想了解更多信息,请访问 <a href="https://bk.cuixiaoyan.xyz/">https://bk.cuixiaoyan.xyz/</a>
</div>
</div>
</div>
</body>
</html>
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class MailTest {
@Autowired
private JavaMailComponent javaMailComponent;
@Test
public void test() {
this.javaMailComponent.sendMail("56696508@qq.com");
}
}
@Component
public class Schedule {
@Scheduled(fixedRate = 2000)
public void task() {
System.out.println("启动定时任务:" + new Date());
}
}
使用 @Scheduled 定义任务执行时间,代码中表示每隔 2 秒执行一次任务。
只需在 Spring Boot 的启动类上添加 @EnableScheduling 后,启动项目即可。
默认情况下,Spring Task 使用一条线程串行的执行所有的定时任务。为了提高执行效率,我们需要手动编写一个线程池实现定时任务的并行执行。
@Configuration
@EnableScheduling
public class AsyncTaskConfig implements SchedulingConfigurer, AsyncConfigurer {
//线程池线程数量
private int corePoolSize = 5;
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.initialize();//初始化线程池
scheduler.setPoolSize(corePoolSize);//线程池容量
return scheduler;
}
@Override
public Executor getAsyncExecutor() {
Executor executor = this.taskScheduler();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.setTaskScheduler(taskScheduler());
}
}
添加依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
重新创建一个配置类,如下:
@Configuration
@EnableSwagger2
public class Swagger2Configuration extends WebMvcConfigurationSupport {
@Bean
public Docket accessToken() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("api")// 定义组
.select() // 选择那些路径和 api 会生成 document
.apis(RequestHandlerSelectors.basePackage("com.cxy.template.controller")) // 拦截的包路径
.paths(PathSelectors.regex("/*/.*"))// 拦截的接口路径
.build() // 创建
.apiInfo(apiInfo()); // 配置说明
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()//
.title("Spring Boot 之 Web 篇")// 标题
.description("spring boot Web 相关内容")// 描述
.termsOfServiceUrl("https://bk.cuixiaoyan.xyz/")//
.contact(new Contact("moonlightL", "https://bk.cuixiaoyan.xyz/", "cuixiaoyande@163.com"))// 联系
.version("1.0")// 版本
.build();
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决静态资源无法访问
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
// 解决swagger无法访问
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
// 解决swagger的js文件无法访问
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
为了能更好的说明接口信息,我们还可以在 Controller 类上使用 Swagger2 相关注解说明信息。 我们以 FastJsonController 为例:
@Api(value = "FastJson测试", tags = { "测试接口" })
@RestController
@RequestMapping("fastjson")
public class FastJsonController {
@ApiOperation("获取用户信息")
@ApiImplicitParam(name = "name", value = "用户名", dataType = "string", paramType = "query")
@GetMapping("/test/{name}")
public User test(@PathVariable("name") String name) {
User user = new User();
user.setId(1);
user.setUsername(name);
user.setPassword("jack123");
user.setBirthday(new Date());
return user;
}
}
注意,上边的方法是用 @GetMapping 注解,如果只是使用 @RequestMapping 注解,不配置 method 属性,那么 API 文档会生成 7 种请求方式。
启动项目,打开浏览器访问 http://localhost:8080/swagger-ui.html