程序自动将本地图片上传到微博相册(二)

时间 2021/3/28 0:33:48 加载中...

程序自动将本地图片上传到微博相册(一)
程序自动将本地图片上传到微博相册(二)


目的

在 “程序自动将本地图片上传到微博相册(一)” 中我们实现了本地图片上传到微博相册的功能,这里我们对其进一步完善。
完善内容有:

1、目前的 ChromeDriver 路径是写死在代码中的 → 修改成 可配置的
2、上传的本地文件是写死在代码中的 → 修改成从数据库读取的

知识点

Spring Boot 配置
Spring Boot 配置数据源

配置 ChromeDriver

1、在 application.yml 中添加配置

  1. chrome-driver:
  2. path: /Users/adminqian/shen/soft/chromeDriver/chromedriver

2、添加 config 文件夹,后面其他的配置也放在此文件夹内。新建类 ChromeDriverConf,内容如下:

  1. import org.springframework.boot.context.properties.ConfigurationProperties;
  2. import org.springframework.context.annotation.Configuration;
  3. @Configuration
  4. @ConfigurationProperties(prefix = "chrome-driver")
  5. public class ChromeDriverConf {
  6. private String path;
  7. public String getPath() {
  8. return path;
  9. }
  10. public void setPath(String path) {
  11. this.path = path;
  12. }
  13. }

在控制器中添加 ChromeDriverConf,并修改 start 方法

  1. @Autowired
  2. private ChromeDriverConf chromeDriverConf;
  3. @ResponseBody
  4. @GetMapping("/start")
  5. public String start() {
  6. gl>System.setProperty("webdriver.chrome.driver", chromeDriverConf.getPath());
  7. ChromeOptions chromeOptions = new ChromeOptions();
  8. driver = new ChromeDriver(chromeOptions);
  9. driver.get("https://photo.weibo.com/upload/index?prel=p5_1#3500590076519405");
  10. return "chrome driver 初始化成功";
  11. }

配置数据库

我们将需要上传到微博相册的图片信息,存在数据库中,然后读取数据库获取需要处理的图片。

我们先构建数据库,数据库脚本如下:

  1. create DATABASE lab;
  2. CREATE TABLE `file` (
  3. `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  4. `name` VARCHAR(200) DEFAULT '' COMMENT '文件名字',
  5. `serverPath` VARCHAR(300) DEFAULT '' COMMENT '文件路径',
  6. `weiboSyncState` int(11) DEFAULT '0' COMMENT '微博同步状态:0-待同步,1-同步成功,2-同步失败'
  7. `weiboSyncMsg` VARCHAR(2500) DEFAULT '' COMMENT '同步信息',
  8. `weiboId` varchar(200) DEFAULT '' COMMENT '微博图片id',
  9. `createTime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  10. `status` tinyint(4) DEFAULT '1' COMMENT '记录状态:0-删除 1-正常',
  11. PRIMARY KEY (`id`) USING BTREE
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='文件表';

程序增加访问数据库的功能

数据库建立之后,在程序中的基本改动如下

(1)添加依赖
在 pom.xml 文件中添加 MySQL 访问的驱动程序 和 连接池,连接池使用的是 HikariCP。

  1. <dependency>
  2. <groupId>com.zaxxer</groupId>
  3. <artifactId>HikariCP</artifactId>
  4. <version>3.4.5</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>mysql</groupId>
  8. <artifactId>mysql-connector-java</artifactId>
  9. <version>8.0.12</version>
  10. </dependency>

(2)在 application.yml 中添加数据源配置

  1. spring:
  2. datasource:
  3. mysql:
  4. JdbcUrl: jdbc:mysql://127.0.0.1:3306/lab?useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
  5. DriverClassName: com.mysql.cj.jdbc.Driver
  6. Username: root
  7. Password: 123456

(3)在项目中补充数据库访问需要的文件,并将其放在 db 目录下

  • DataSourceItem.java
  • DBHelper.java
  • IResultHandler.java
  • PagedResponse.java
  • ParamsHelper.java
  • ResultSetHelper.java

这些文件可以在这里下载:
https://github.com/shenqiangbin/toutiao/tree/weiboDemo/weibotest/src/main/java/com/sqber/weibotest/db

主要用到的是 DBHelper 类,通过传递一个 DataSource 后,就可以执行基本的增删改查、分页查询等操作。还可以动态传递数据源配置,去不同的数据源查询。

(4)配置数据源

在 config 文件夹下新增 DataSourceConf.java 文件。这里可以配置多个数据源,只需要在 application 配置文件中添加数据源信息即可。这里只用到一个 MySQL 数据源。然后再通过默认的数据源构建一个默认的 DBHelper。在使用的时候使用 @Autowired 注入上 DBHelper 即可。

  1. package com.sqber.weibotest.config;
  2. import com.sqber.weibotest.db.DBHelper;
  3. //import org.springframework.beans.factory.annotation.Qualifier;
  4. import org.springframework.boot.context.properties.ConfigurationProperties;
  5. import org.springframework.boot.jdbc.DataSourceBuilder;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.context.annotation.Primary;
  9. import javax.sql.DataSource;
  10. @Configuration
  11. public class DataSourceConf {
  12. @Bean
  13. @Primary
  14. @ConfigurationProperties(prefix = "spring.datasource.mysql")
  15. public DataSource dataSource() {
  16. return DataSourceBuilder.create().build();
  17. }
  18. @Bean
  19. @Primary
  20. public DBHelper primaryDbHelper(DataSource dataSource) {
  21. return new DBHelper(dataSource);
  22. }
  23. // 多数据源:在有一个数据源时,配置如下
  24. // @Bean("secondDataSource")
  25. // @ConfigurationProperties(prefix = "spring.datasource.psg") // application.properteis中对应属性的前缀
  26. // public DataSource dataSource2() {
  27. // return DataSourceBuilder.create().build();
  28. // }
  29. //
  30. // @Bean("postgre")
  31. // public DBHelper postgreSqlHelper(@Qualifier("secondDataSource") DataSource dataSource) {
  32. // return new DBHelper(dataSource);
  33. // }
  34. // /**
  35. // * 其他地方使用:
  36. // * @Autowired
  37. // * @Qualifier("postgre")
  38. // * private DBHelper postgreHelper;
  39. // */
  40. }
  41. No newline at end of file

文件表业务逻辑

程序基本的访问数据库功能有了之后,我们来编写文件表的业务逻辑。
我们再新增三个文件夹 dao 、 service 和 model 。

dao 就是 数据库访问层 相关的文件
service 就是 服务层 相关的文件
model 就是 实体 相关的文件

(1)新增数据库访问:在 dao 文件夹新增 FileDao.java 文件。业务逻辑有:

  • 【新增】新增一个文件
  • 【查询】查询未处理的10个文件
  • 【更新】更新文件的状态、微博id

注意: 操作数据库时,一般使用 SQL参数化 的形式进行操作,避免 SQL注入

具体内容如下:

  1. package com.sqber.weibotest.dao;
  2. import com.sqber.weibotest.db.DBHelper;
  3. import com.sqber.weibotest.db.ParamsHelper;
  4. import com.sqber.weibotest.model.MyFile;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Repository;
  7. import java.sql.SQLException;
  8. import java.util.List;
  9. @Repository
  10. public class FileDao {
  11. @Autowired
  12. private DBHelper dbHelper;
  13. public int add(String name, String serverPath) throws SQLException {
  14. Object[] arr = new Object[]{
  15. name,
  16. serverPath
  17. };
  18. String sql = String.format(
  19. "insert file(name,serverPath) values(%s)",
  20. ParamsHelper.createStr(arr.length));
  21. return dbHelper.add(sql, arr);
  22. }
  23. /**
  24. * 获取需要处理的文件(获取10个)
  25. *
  26. * @return
  27. * @throws Exception
  28. */
  29. public List<MyFile> getNeedHandle() throws Exception {
  30. String sql = "select * from file where weiboSyncState = " + MyFile.WeiboSyncState_NOHand + " limit 10";
  31. return dbHelper.simpleQuery(sql, null, MyFile.class);
  32. }
  33. public void updateState(Long id, Integer state, String info, String picId) throws SQLException {
  34. String sql = "update file set weiboSyncState = ?,weiboSyncMsg=?,weiboId=? where id = ?";
  35. dbHelper.update(sql, new Object[]{state, info, picId, id});
  36. }
  37. }

(2)新增实体: 在 model 文件夹新增一个 MyFile.java。内容如下:

  1. package com.sqber.weibotest.model;
  2. public class MyFile {
  3. public static final Integer WeiboSyncState_NOHand = 0;
  4. public static final Integer WeiboSyncState_SUCCESS = 1;
  5. public static final Integer WeiboSyncState_FAIL = 2;
  6. private Long id;
  7. private String name;
  8. private String serverPath;
  9. private Integer weiboSyncState;
  10. // getter setter 略
  11. }

(3)新增文件服务:在 Service 层新增 FileService.java 文件。内容如下:

  1. package com.sqber.weibotest.service;
  2. import com.sqber.weibotest.dao.FileDao;
  3. import com.sqber.weibotest.model.MyFile;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Service;
  6. import java.sql.SQLException;
  7. import java.util.List;
  8. @Service
  9. public class FileService {
  10. @Autowired
  11. private FileDao fileDao;
  12. // 增
  13. public int add(String name, String serverPath) throws SQLException {
  14. return fileDao.add(name, serverPath);
  15. }
  16. // 删
  17. // 改
  18. public void updateState(Long id, Integer state, String info, String picId) throws SQLException {
  19. fileDao.updateState(id,state,info,picId);
  20. }
  21. // 查
  22. public List<MyFile> getNeedHandle() throws Exception {
  23. return fileDao.getNeedHandle();
  24. }
  25. }

(5) 然后在 HomeCtroller 中新增一个从数据库读取,并同步到微博相册的接口

  1. /**
  2. * 将数据库中待同步的文件同步到微博相册
  3. * @return
  4. * @throws Exception
  5. */
  6. @ResponseBody
  7. @GetMapping("/browser/db")
  8. public String db() throws Exception {
  9. List<MyFile> list = fileService.getNeedHandle();
  10. for(MyFile item : list){
  11. String picId = this.go(item.getServerPath());
  12. fileService.updateState(item.getId(), MyFile.WeiboSyncState_SUCCESS, "", picId);
  13. //String pic = "https://wx4.sinaimg.cn/mw690/" + str + ".jpg";
  14. //String pic = "https://wx4.sinaimg.cn/large/8e2ef8f7gy1gp171tmfldj20go0l21kx.jpg";
  15. //return pic;
  16. }
  17. return "ok";
  18. }

在页面上调用 /browser/db 就可以测试是否能够将数据库中记录的本地文件上传到微博相册(先要调用 /start 接口登录微博)。
我们在数据库中存的只是一个 id 信息。使用的时候可以拼接一下地址。

String pic = "https://wx4.sinaimg.cn/mw690/" + str + ".jpg"; 这个是压缩图片
String pic = "https://wx4.sinaimg.cn/large/" + str + ".jpg"; 这个是原始图片


至此,可配置 和 数据库读取 就完了。
后续我们将数据库读取修改成定时任务模式,不用再人为干预,我们只是往数据库插入数据,定时任务去将图片上传到微博相册。

扫码分享
版权说明
作者:SQBER
文章来源:http://www.sqber.com/articles/auto-upload-local-file-to-weibo-2.html
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。