sprintboot

一、邮件发送

使用springboot自带的邮件系统就能实现邮件的发送,首先导入依赖:

1、新建springboot项目,添加依赖

1<dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-mail</artifactId> 4</dependency>

2、以qq邮箱为例,在application文件中配置邮箱信息

1spring.mail.host=smtp.qq.com 2spring.mail.username=用户名 3spring.mail.password=密码 #为客户端登录授权码,并不是邮箱登录密码 4spring.mail.properties.mail.smtp.auth=true 5spring.mail.properties.mail.smtp.starttls.enable=true 6spring.mail.properties.mail.smtp.starttls.required=true

授权码获取:

选择开启,点击后会让你用绑定的手机号发送一条信息,发送后点击已发送就会看到自己的登录授权码,一定记得要保存修改。不然会出问题

3、编写一个简单的测试用例

1@Autowired 2private mailSender;//注入邮件发送对象。会自动加载配置文件中的邮件设置 3 4@Test 5public void contextLoads() { 6 7 MimeMessage mimeMessage = mailSender.createMimeMessage(); 8 MimeMessageHelper helper; 9 String[] strings = new String[3]; 10 strings[2]="email1"; 11 strings[1]="email2"; 12 strings[0]="email3"; 13 try { 14 helper = new MimeMessageHelper(mimeMessage, true); 15 helper.setFrom("email");//发送人 16 helper.setTo("emailTo");//邮件接收人 17 helper.setCc(strings);//抄送邮件接收人,可以抄送多个 18 helper.setSubject("群发邮件");//邮件标题 19FileSystemResource file = new FileSystemResource(new File("detail.jpg")); 20helper.addAttachment("附件-1.jpg", file);//发送附件 21helper.addInline("jpg", file); 22 23 helper.setText("<html><body> <div>群发邮件</div></body></html>", true);//可以使用html 24 mailSender.send(mimeMessage); 25 } catch (MessagingException e) { 26 27 e.printStackTrace(); 28 }

4、上述工作完成后启动测试类,即可成功发送指定内容至指定邮箱。

在这个过程中遇到了几个问题,这里记录一下:

问题1:Caused by: javax.mail.AuthenticationFailedException: 535 Error: ÇëʹÓÃÊÚȨÂëµÇ¼¡£ÏêÇéÇë¿´

这是在application.properties中设置的密码不是授权码或者属性值后面带有空格等导致的

问题2:Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 Mailbox not found or access denied

这是由于邮箱地址填写错误导致的。还有就是使用企业邮箱时,在发送的邮箱中由于有人离职导致该地址不存在而导致发送异常。

至此一个简单的邮件发送就完成了,然而在实际开发中仅仅这样是不能满足我们的开发需求的,所以我们要对其进行加工,让变得更加丰满。

二、进阶——定时任务

我们时常会遇到需要定时处理某个任务的情况,比如定时发送邮件至某个或几个相关人员的邮箱,那么应该怎么做呢。接下来我们就看看如何通过定时任务将邮件发送至指定邮箱。

1、添加定时任务的依赖

1<dependency> 2 <groupId>org.quartz-scheduler</groupId> 3 <artifactId>quartz</artifactId> 4 <version>2.3.0</version> 5 <exclusions> 6 <exclusion> 7 <artifactId>slf4j-api</artifactId> 8 <groupId>org.slf4j</groupId> 9 </exclusion> 10 <exclusion> 11 <artifactId>HikariCP-java6</artifactId> 12 <groupId>com.zaxxer</groupId> 13 </exclusion> 14 </exclusions> 15</dependency>

这里我没有使用springboot自带的定时任务触发器,而是使用quartz,话不多说,直接上代码。

1@RestController 2@RequestMapping("/job")public class JobController { 3 4 private static final Logger LOGGER = LoggerFactory.getLogger(JobController.class); 5 6 @Autowired 7 @Qualifier("scheduler") 8 private Scheduler scheduler; 9 10 11 @SuppressWarnings({"unchecked", "rawtypes"}) 12 @RequestMapping("/add") 13 @ApiOperation(value = "新建任务", notes = "新建任务", httpMethod = "POST") 14 @ApiImplicitParams({ 15 @ApiImplicitParam(paramType = "query", name = "jobName", dataType = "String", value = "任务名称"), 16 @ApiImplicitParam(paramType = "query", name = "jobGroup", dataType = "String", value = "任务分组"), 17 @ApiImplicitParam(paramType = "query", name = "jobClassName", dataType = "String", value = "任务类全路径"), 18 @ApiImplicitParam(paramType = "query", name = "description", dataType = "String", value = "任务描述"), 19 @ApiImplicitParam(paramType = "query", name = "cronExpression", dataType = "String", value = "执行时间"), 20 @ApiImplicitParam(paramType = "query", name = "oldJobName", dataType = "String", value = "原任务名称"), 21 @ApiImplicitParam(paramType = "query", name = "oldJobGroup", dataType = "String", value = "原任务分组"), 22 @ApiImplicitParam(paramType = "query", name = "endTime", dataType = "String", value = "任务结束时间") 23 }) 24 public String save(Quartz quartz) { 25 26 LOGGER.info("新增任务"); 27 //时间格式化 28 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 29 30 try { 31// Date parse = sdf.parse("2019-07-25 16:30:00"); 32 //将输入的任务过期时间格式化为特定格式 33 Date parse = sdf.parse(quartz.getEndTime()); 34 //将任务开始时间格式化 35 Date startTime = sdf.parse("2019-07-01 22:32:12"); 36 // 获取Scheduler实例、废弃、使用自动注入的scheduler、否则spring的service将无法注入 37 // Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); 38 // 如果是修改,展示旧的任务 39 if (quartz.getOldJobGroup() != null) { 40 //生成任务唯一key 41 JobKey key = new JobKey(quartz.getOldJobName(), quartz.getOldJobGroup()); 42 scheduler.deleteJob(key); 43 } 44 //任务执行类 45 Class cls = Class.forName(quartz.getJobClassName()); 46 cls.newInstance(); 47 // 构建job信息 48 JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(), 49 quartz.getJobGroup()) 50 .withDescription(quartz.getDescription()).build(); 51 // 触发时间点 52 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression()); 53 Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger" + quartz.getJobName(), quartz.getJobGroup()) 54 .startNow().withSchedule(cronScheduleBuilder).endAt(parse).startAt(startTime).build(); 55 // 交由scheduler安排触发 56 scheduler.scheduleJob(job, trigger); 57 } catch (Exception e) { 58 e.printStackTrace(); 59 return "failure"; 60 } 61 return "success"; 62 } 63 64 @PostMapping("/remove") 65 @ApiOperation(value = "移除任务", notes = "移除任务", httpMethod = "POST") 66 @ApiImplicitParams({ 67 @ApiImplicitParam(paramType = "query", name = "jobName", dataType = "String", value = "任务名称"), 68 @ApiImplicitParam(paramType = "query", name = "jobGroup", dataType = "String", value = "任务分组") 69 }) 70 public String remove(Quartz quartz) { 71 try { 72 73 TriggerKey triggerKey = TriggerKey.triggerKey(quartz.getJobName(), quartz.getJobGroup()); 74 // 停止触发器 75 scheduler.pauseTrigger(triggerKey); 76 // 移除触发器 77 scheduler.unscheduleJob(triggerKey); 78 // 删除任务 79 scheduler.deleteJob(JobKey.jobKey(quartz.getJobName(), quartz.getJobGroup())); 80 LOGGER.info("removeJob:" + JobKey.jobKey(quartz.getJobName())); 81 } catch (Exception e) { 82 e.printStackTrace(); 83 return "failer"; 84 } 85 return "success"; 86 } 87 88}

任务job:

1public class MailSendJob implements Job, Serializable { 2 3 private static final Logger LOGGER = LoggerFactory.getLogger(MailSendJob.class); 4 private static final long serialVersionUID = 1L; 5 6 private static final String URL = ""; 7 private static final String NAME = ""; 8 private static final String PASSWORD = ""; 9 10 @Autowired 11 private JavaMailSender mailSender;//启动类添加注解后,注入这个注解会自动加载配置文件中的邮件配置 12 13 @Override 14 public void execute(JobExecutionContext context) throws JobExecutionException { 15 16 MimeMessage mimeMessage = mailSender.createMimeMessage(); 17 MimeMessageHelper helper; 18 String[] strings = new String[2];//构建需要发送邮件的邮箱数组 19 strings[1] = "mail3"; 20 strings[0] = "mail"; 21 String filePath = writeCsv("test"); 22 try { 23 helper = new MimeMessageHelper(mimeMessage, true); 24 helper.setFrom("mail1");//发送人 25 helper.setTo("mail2");//邮件接收人 26 helper.setCc(strings);//抄送邮件接收人 27 helper.setSubject("发送带抄送的邮件");//邮件标题 28 helper.setText("<html><body> <div>发送带抄送的邮件</div></body></html>", true);//可以使用html 29 FileSystemResource file = new FileSystemResource(new File(filePath));//获取需要发送的附件文件 30 String fileName = filePath.substring(filePath.lastIndexOf(File.pathSeparator) + 1);//获取文件名 31 helper.addAttachment(fileName, file);//添加附件 32 mailSender.send(mimeMessage);//发送带附件的邮件 33 34 } catch (MessagingException e) { 35 e.printStackTrace(); 36 LOGGER.error("任務執行失敗"); 37 } finally { 38 //最后删除在磁盘上生成的文件 39 File file1 = new File(filePath); 40 if (file1.exists() && file1.isFile()) { 41 file1.delete(); 42 } 43 } 44 } 45 46 47 private String writeCsv(String name) { 48 49 String home = System.getProperty("user.home") + "\\Downloads\\" + name + "." + "csv"; 50// String home = "d:/detail.csv"; 51 try { 52 //1.加载驱动程序 53 Class.forName("com.mysql.jdbc.Driver"); 54// Class.forName("org.postgresql.Driver"); 55 //2.获得数据库的连接 56 Connection conn = DriverManager.getConnection(URL, NAME, PASSWORD); 57 //3.通过数据库的连接操作数据库,实现增删改查 58 Statement stmt = conn.createStatement(); 59 Statement statement = conn.createStatement(); 60 // TODO 获取数据 61 ResultSet resultSet = statement.executeQuery(" select * from area_code order by code limit 50"); 62// ResultSet resultSet = statement.executeQuery("select a.*,b.* from a join b on a.id=b.id where a.id<1000"); 63 ResultSetMetaData metaData = resultSet.getMetaData(); 64 int columnCount = metaData.getColumnCount(); 65 FileOutputStream out = new FileOutputStream(home); 66 67 CsvWriter csvWriter = new CsvWriter(home, ',', Charset.forName("UTF-8")); 68 //写入表头信息 69 String[] header = new String[columnCount]; 70 for (int i = 0; i < columnCount; i++) { 71 header[i] = metaData.getColumnName(i + 1); 72 } 73 csvWriter.writeRecord(header); 74 //写入内容信息 75 while (resultSet.next()) { 76 77 for (int i = 0; i < columnCount; i++) { 78 79 csvWriter.write(resultSet.getString(metaData.getColumnName(i + 1))); 80 } 81 csvWriter.endRecord(); 82 } 83 84 //关闭写入的流 85 csvWriter.close(); 86 File fileLoad = new File(home); 87 FileInputStream in = new java.io.FileInputStream(fileLoad); 88 //每次写入10240个字节 89 byte[] b = new byte[10240]; 90 int n; 91 while ((n = in.read(b)) != -1) { 92 out.write(b, 0, n); //每次写入out1024字节 93 } 94 out.close(); 95 in.close(); 96 System.out.println(home); 97 return home; 98 } catch (Exception e) { 99 100 e.printStackTrace(); 101 return null; 102 } 103 104 } 105}

需要几个配置:

1@Configuration 2public class QuartzConfig { 3 4 @Autowired 5 private SpringJobFactory springJobFactory; 6 7 @Bean(name = "schedulerFactory") 8 public SchedulerFactoryBean schedulerFactoryBean() throws IOException { 9 SchedulerFactoryBean factory = new SchedulerFactoryBean(); 10 factory.setAutoStartup(true); 11 // 延时5秒启动 12 factory.setStartupDelay(5); 13 factory.setQuartzProperties(quartzProperties()); 14 factory.setJobFactory(springJobFactory); 15 return factory; 16 } 17 18 @Bean 19 public Properties quartzProperties() throws IOException { 20 PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); 21 propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));//任务信息库表信息配置文件 22 propertiesFactoryBean.afterPropertiesSet(); 23 return propertiesFactoryBean.getObject(); 24 } 25 26 /** 27 * quartz初始化监听器 28 * 29 * @return 30 */ 31 @Bean 32 public QuartzInitializerListener executorListener() { 33 return new QuartzInitializerListener(); 34 } 35 36 /** 37 * 通过SchedulerFactoryBean获取Scheduler的实例 38 * 39 * @return 40 * @throws IOException 41 */ 42 @Bean(name = "scheduler") 43 public Scheduler scheduler() throws IOException { 44 return schedulerFactoryBean().getScheduler(); 45 } 46 47} 48 49@Component 50public class SpringJobFactory extends AdaptableJobFactory { 51 @Autowired 52 private AutowireCapableBeanFactory capableBeanFactory; 53 54 @Override 55 protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { 56 // 调用父类的方法 57 Object jobInstance = super.createJobInstance(bundle); 58 // 进行注入 59 capableBeanFactory.autowireBean(jobInstance); 60 return jobInstance; 61 } 62}

任务说明:使用定时任务定时获取数据库中的数据信息,将统计数据以excel定时发送到指定负责人的邮箱

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )