微信公众号上传永久图片素材(将阿里云图片上传至微信公众号图片素材)
程序员文章站
2022-06-23 11:15:27
需求是公众号添加关键词回复,但是关键词有近1000个。每个关键词回复一张图片思路:1、每张图片的名字命名为关键词2、然后统一上传至阿里云。3、下载阿里云文件夹全部文件将文件信息保存至本地数据库4、上传至微信公众号图片素材。这样可以做成总运营平台自定义关键词+图片以一张图片举例;以下为demo,该批量处理还是批量处理,该异步处理还是得异步处理在项目启动的时候将图片地址等信息添加到本地数据库,上传素材图片实体类package com.shinedata.e....
需求是公众号添加关键词回复,但是关键词有近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