今天用springboot对接微信公众号,用户关注公众号时,需要自动推送小程序给客户,但是公众号的自动回复消息接口中不支持推送小程序卡片,详见微信开发文档,所以需要用到公众号的客服消息api,客服消息可以推送小程序卡片
但是其中有一个参数:thumb_media_id,它是缩略图/小程序卡片图片的媒体ID,所以需要调用上传图片素材的接口,获取这个id,我现在调用的是新增临时素材的接口
废话少说,直接上代码
@PostMapping("upload_media")
public JSONObject upload_media(@RequestPart("file") MultipartFile file) throws IOException {
return iWxMessageService.upload_media(file);
}
/**
* 新增图片素材
* @return
*/
JSONObject upload_media(MultipartFile file) throws IOException;
@Override
public JSONObject upload_media(MultipartFile file) throws IOException {
JSONObject jsonObject = WxUtil.upload_media(file.getInputStream(), getToken());
return jsonObject;
}
public static JSONObject upload_media(InputStream inputStream, String access_token) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
byte[] mediaData = byteArrayOutputStream.toByteArray();
return HttpClientUtil.postHttpJson("https://api.weixin.qq.com/cgi-bin/media/upload?access_token=" + access_token + "&type=image", mediaData);
}
/**
* url为请求地址,data为请求体
* @param url
* @return
* @throws Exception
*/
public static JSONObject postHttpJson(String url, byte[] mediaData) {
try {
java.net.URL realUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
//设置请求头
// connection.setRequestProperty("Authorization", "Bearer ");
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
// 设置请求正文,将data替换为您要发送的数据
OutputStream os = connection.getOutputStream();
// 写入type参数
writeFormField(os, "type", "image");
// 写入media参数
writeBinaryFile(os, "media", "image.jpg", "image/jpeg", mediaData); // 假设是JPEG格式的图片
// 写入结束标识
os.write(("--" + BOUNDARY + "--\r\n").getBytes("UTF-8"));
os.flush();
os.close();
// 建立实际的连接
connection.connect();
//请求成功
if (connection.getResponseCode() == 200) {
//执行getInputStream方法才实际发送http请求
InputStream is = connection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//10KB的缓存
byte[] buffer = new byte[10240];
int len = 0;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
String jsonString = baos.toString();
baos.close();
is.close();
JSONObject jsonArray = JSONObject.parseObject(jsonString);
return jsonArray;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
// 写入表单字段
private static void writeFormField(OutputStream os, String fieldName, String fieldValue) throws IOException {
os.write(("--" + BOUNDARY + "\r\n").getBytes("UTF-8"));
os.write(("Content-Disposition: form-data; name=\"" + fieldName + "\"\r\n").getBytes("UTF-8"));
os.write("\r\n".getBytes("UTF-8"));
os.write((fieldValue + "\r\n").getBytes("UTF-8"));
}
// 写入二进制文件
private static void writeBinaryFile(OutputStream os, String fieldName, String fileName, String contentType, byte[] fileData) throws IOException {
os.write(("--" + BOUNDARY + "\r\n").getBytes("UTF-8"));
os.write(("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"\r\n").getBytes("UTF-8"));
os.write(("Content-Type: " + contentType + "\r\n").getBytes("UTF-8"));
os.write("\r\n".getBytes("UTF-8"));
os.write(fileData);
os.write("\r\n".getBytes("UTF-8"));
}
// 生成一个唯一的 BOUNDARY
static String generateBoundary() {
SecureRandom random = new SecureRandom();
byte[] randomBytes = new byte[16];
random.nextBytes(randomBytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes);
}
调用成功!