需求是公众号添加关键词回复,但是关键词有近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 /12/29 13:28*/@Data@Entity@Table(name = "t_wechat_keyword")public class WechatKeyword {@Idprivate Long id;private Date createTime;private Date updateTime;//关键词private String keyword;//图片素材mediaIdprivate 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.mandLineRunner;import org.ponent;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.Map;/*** @ClassName YbxzKeywordReplyRunner* @Author yupanpan* @Date /12/29 10:51*/@Componentpublic class YbxzKeywordReplyRunner implements CommandLineRunner {@Autowiredprivate WechatKeywordService wechatKeywordService;@Overridepublic 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 mons.lang3.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.FileNotFoundException;import java.io.InputStream;import .URL;import java.util.Date;import java.util.HashMap;import java.util.Map;public class ImageOssUtils {private static final Loggerlogger= LoggerFactory.getLogger(ImageOssUtils.class);private static Stringendpoint= "oss-cn-";private static StringaccessKeyId= "xxxxxxxxxxxx";private static StringaccessKeySecret= "xxxxxxxxxxxx";private static StringbucketName= "shinedata-edu";private static OSSClientossClient;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));}// 关闭clientossClient.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./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_9U4c3MhGHzvkJGhi7Yi6GZ2sString 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 .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);.HttpURLConnection connection = (.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;}}
测试结果为添加到微信公众号图片素材
如果觉得《微信公众号上传永久图片素材(将阿里云图片上传至微信公众号图片素材)》对你有帮助,请点赞、收藏,并留下你的观点哦!