微信公众号上传永久图片素材(将阿里云图片上传至微信公众号图片素材)

需求是公众号添加关键词回复,但是关键词有近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

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐