需求是公众号添加关键词回复,但是关键词有近1000个。每个关键词回复一张图片
思路:
1、每张图片的名字命名为关键词
2、然后统一上传至阿里云。
3、下载阿里云文件夹全部文件将文件信息保存至本地数据库,原来设计只保存微信的图片地址,考虑到后面拓展运营平台自定义关键词回复图片这些,多了个阿里云的地址
4、上传至微信公众号图片素材。
这样可以做成总运营平台自定义关键词+图片
以一张图片举例;
以下为demo,该批量处理还是批量处理,该异步处理还是得异步处理
在项目启动的时候将图片地址等信息添加到本地数据库,上传素材图片
实体类
package com.shinedata.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
/**
* @ClassName WechatKeyword
* @Author yupanpan
* @Date 2020/12/29 13:28
*/
@Data
@Entity
@Table(name = "t_wechat_keyword")
public class WechatKeyword {
@Id
private Long id;
private Date createTime;
private Date updateTime;
//关键词
private String keyword;
//图片素材mediaId
private String mediaId;
//阿里云图片地址
private String aliOssImageUrl;
//腾讯素材库图片地址
private String tencentImageUrl;
//text为文本 image为图片 voice为语音 video为视频 music为音乐 news为图文
private String msgType;
private Integer deleteStatus=0;
}
package com.shinedata.init;
import com.shinedata.constant.Constants;
import com.shinedata.constant.wechat.WechatConstants;
import com.shinedata.constant.wechat.WechatUtils;
import com.shinedata.entity.WechatKeyword;
import com.shinedata.server.wechat.WechatKeywordService;
import com.shinedata.util.IdUtils;
import com.shinedata.util.ImageOssUtils;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @ClassName YbxzKeywordReplyRunner
* @Author yupanpan
* @Date 2020/12/29 10:51
*/
@Component
public class YbxzKeywordReplyRunner implements CommandLineRunner {
@Autowired
private WechatKeywordService wechatKeywordService;
@Override
public void run(String... args) throws Exception {
Date date = new Date();
Map<String, String> fileNames = ImageOssUtils.getFileNames("/wechat/keyword/");
List<WechatKeyword> wechatKeywords = new ArrayList<>();
for (Map.Entry<String, String> entry : fileNames.entrySet()) {
WechatKeyword wechatKeyword = new WechatKeyword();
wechatKeyword.setId(IdUtils.getId());
wechatKeyword.setCreateTime(date);
wechatKeyword.setUpdateTime(date);
wechatKeyword.setMsgType(WechatConstants.MessageMsgType.IMAGE.getMsgType());
wechatKeyword.setKeyword(entry.getKey());
wechatKeyword.setAliOssImageUrl(entry.getValue());
wechatKeyword.setDeleteStatus(Constants.DeleteStatus.ACTIVE.getCode());
wechatKeywords.add(wechatKeyword);
wechatKeywordService.insert(wechatKeyword);
}
for (WechatKeyword wechatKeyword : wechatKeywords) {
Thread.sleep(3000);
JSONObject jsonObject = WechatUtils.uploadMaterialImage(wechatKeyword.getAliOssImageUrl(),
wechatKeyword.getMsgType());
wechatKeyword.setMediaId(jsonObject.get("media_id").toString());
wechatKeyword.setTencentImageUrl(jsonObject.get("url").toString());
wechatKeywordService.update(wechatKeyword);
}
}
}
阿里云文件处理,获取文件信息
package com.shinedata.util;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class ImageOssUtils {
private static final Logger logger = LoggerFactory.getLogger(ImageOssUtils.class);
private static String endpoint = "oss-cn-shanghai.aliyuncs.com";
private static String accessKeyId = "xxxxxxxxxxxx";
private static String accessKeySecret = "xxxxxxxxxxxx";
private static String bucketName = "shinedata-edu";
private static OSSClient ossClient;
private static void init() {
if (ossClient == null) {
ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
}
}
public static void imageUpload( InputStream inputStream,
String fileKey) throws FileNotFoundException {
init();
if (ossClient != null) {
ossClient.putObject(bucketName, fileKey, inputStream);
}
logger.info("image upload success .......");
}
// 获取文件列表 文件名对应文件地址
// filePath 下载文件夹或者文件路径,a/b/c.avi 不加/根路径 文件夹以/结尾
public static Map<String,String> getFileNames(String filePath) {
Map<String,String> fileMap=new HashMap<>();
String http="https://";
if(StringUtils.isNotBlank(filePath)&&filePath.startsWith("/")){
filePath=filePath.substring(1);
}
init();
// 构造ListObjectsRequest请求
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
//Delimiter 设置为 “/” 时,罗列该文件夹下的文件
listObjectsRequest.setDelimiter("/");
//Prefix 设为某个文件夹名,罗列以此 Prefix 开头的文件
listObjectsRequest.setPrefix(filePath);
ObjectListing listing = ossClient.listObjects(listObjectsRequest);
// 遍历所有Object:目录下的文件
for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
//key:fun/like/001.avi等,即:Bucket中存储文件的路径
String key = objectSummary.getKey();
String bucketName = objectSummary.getBucketName();
String url=http+bucketName+"."+endpoint+"/"+key;
String fileName = key.replace(filePath, "");
if(StringUtils.isNotBlank(fileName.trim())){
fileName=fileName.split("[.]")[0];
fileMap.put(fileName,url);
}
//下载object到文件
// OSSObject ossObject = ossClient.getObject(new GetObjectRequest(bucketName, key));
}
// 关闭client
ossClient.shutdown();
return fileMap;
}
// public static void main(String[] args) {
// Map<String, String> fileNames = getFileNames("/evaluation/");
// System.out.println(fileNames.toString());
// }
public static String getImageUrl(String fileKey) {
init();
if (ossClient != null) {
Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
URL url = ossClient.generatePresignedUrl(bucketName, fileKey, expiration);
return url.toString();
}
return null;
}
public static String getUrl(String fileKey) {
StringBuffer sb = new StringBuffer();
sb.append("https://").append(bucketName).append(".").append(endpoint).append("/")
.append(fileKey);
return sb.toString();
}
}
获取到文件信息
然后保存至数据库(第一张图)
将网络地址图片转成File上传到微信图片素材,更新本地数据库mediaId等信息
public static final String MATERIAL_URL = “https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE”;
/**
* 微信上传图片素材接口
* @param imageUrl
* @param msgType
* @return
*/
public static JSONObject uploadMaterialImage(String imageUrl,String msgType){
File file = FileUtils.urlToFile(imageUrl);
try {
//上传素材
//HPb4PQugmc1j0Dxhf7_9U4c3MhGHzvkJGhi7Yi6GZ2s
String path = WechatConstants.MATERIAL_URL.replace("ACCESS_TOKEN", WechatCache.getAccessToken(false)).replace("TYPE", msgType);
String result = connectHttpsByPost(path, FileUtils.urlToFile(imageUrl));
result = result.replaceAll("[\\\\]", "");
JSONObject resultJSON = JSONObject.fromObject(result);
if (resultJSON != null) {
if (resultJSON.get("media_id") != null) {
Log4jKit.info(resultJSON.get("media_id").toString());
Log4jKit.info("上传" + msgType + "永久素材成功");
return resultJSON;
} else {
Log4jKit.info("上传" + msgType + "永久素材失败");
}
}
} catch (Exception e) {
Log4jKit.info("程序异常---" + e);
} finally {
Log4jKit.info("结束上传" + msgType + "永久素材---------------------");
if(file.exists()){
file.delete();
}
}
return new JSONObject();
}
public static String connectHttpsByPost(String path, File file) throws IOException {
URL url = new URL(path);
HttpURLConnection con = (HttpURLConnection) (url.openConnection());
String result = null;
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false); // post方式不能使用缓存
// 设置请求头信息
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");
// 设置边界
String BOUNDARY = "----------" + System.currentTimeMillis();
con.setRequestProperty("Content-Type",
"multipart/form-data; boundary="
+ BOUNDARY);
// 请求正文信息
// 第一部分:
StringBuilder sb = new StringBuilder();
sb.append("--"); // 必须多两道线
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data;name=\"media\";filelength=\"" + file.length() + "\";filename=\""
+ file.getName() + "\"\r\n");
sb.append("Content-Type:application/octet-stream\r\n\r\n");
byte[] head = sb.toString().getBytes("utf-8");
// 获得输出流
OutputStream out = new DataOutputStream(con.getOutputStream());
// 输出表头
out.write(head);
// 文件正文部分
// 把文件已流文件的方式 推入到url中
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
in.close();
// 结尾部分
byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
out.write(foot);
out.flush();
out.close();
StringBuffer buffer = new StringBuffer();
BufferedReader reader = null;
try {
// 定义BufferedReader输入流来读取URL的响应
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
if (result == null) {
result = buffer.toString();
}
} catch (IOException e) {
Log4jKit.info("发送POST请求出现异常!" + e);
e.printStackTrace();
throw new IOException("数据读取异常");
} finally {
if (reader != null) {
reader.close();
}
}
return result;
}
package com.shinedata.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
/**
* @ClassName FileUtils
*/
public class FileUtils {
/**
* @param fileUrl 资源地址
* @Description: 网络资源转file, 用完以后必须删除该临时文件
* @return: 返回值
*/
public static File urlToFile(String fileUrl) {
String path = System.getProperty("user.dir");
File upload = new File(path, "tmp");
if (!upload.exists()) {
upload.mkdirs();
}
return urlToFile(fileUrl, upload);
}
/**
* @param fileUrl 资源地址
* @param upload 临时文件路径
* @Description: 网络资源转file, 用完以后必须删除该临时文件
* @return: 返回值
*/
public static File urlToFile(String fileUrl, File upload) {
String fileName = fileUrl.substring(fileUrl.lastIndexOf("/"));
FileOutputStream downloadFile = null;
InputStream openStream = null;
File savedFile = null;
try {
savedFile = new File(upload.getAbsolutePath() + fileName);
URL url = new URL(fileUrl);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
openStream = connection.getInputStream();
int index;
byte[] bytes = new byte[1024];
downloadFile = new FileOutputStream(savedFile);
while ((index = openStream.read(bytes)) != -1) {
downloadFile.write(bytes, 0, index);
downloadFile.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (openStream != null) {
openStream.close();
}
if (downloadFile != null) {
downloadFile.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return savedFile;
}
}
测试结果为添加到微信公众号图片素材
本文地址:https://blog.csdn.net/ypp91zr/article/details/111956392