SendTextToAllUserAct.java
package com.weixin.sendmessage;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.URI;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern; /**
* 控制器
*/
public class SendTextToAllUserAct { /**
* 群发文章微信
*
* @param ids 内容id
* @return
*/
@RequestMapping("/content/o_sendToWeixin.do")
public String sendToWeixin(Integer[] ids) { Content[] beans = new Content[ids.length];
for (int i = 0; i < ids.length; i++) {
beans[i] = contentMng.findById(ids[i]); //查询所有要发送的内容
}
sendTextToAllUser(beans);
return null;
} /**
* 群发
*/
public void sendTextToAllUser(Content[] beans) {
String access_token = getToken();
//上传内容到微信
/**
* 上传图文消息素材
* 官方接口文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html#%E4%B8%8A%E4%BC%A0%E5%9B%BE%E6%96%87%E6%B6%88%E6%81%AF%E7%B4%A0%E6%9D%90%E3%80%90%E8%AE%A2%E9%98%85%E5%8F%B7%E4%B8%8E%E6%9C%8D%E5%8A%A1%E5%8F%B7%E8%AE%A4%E8%AF%81%E5%90%8E%E5%9D%87%E5%8F%AF%E7%94%A8%E3%80%91
*/
String articalUploadUrl = "https://api.weixin.qq.com/cgi-bin/media/uploadnews";
String url = articalUploadUrl + "?access_token=" + access_token; String[] str = articalUpload(access_token, beans);
Integer contentCount = 0;
contentCount = Integer.parseInt(str[1]);
if (contentCount > 0) {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
HttpPost post = new HttpPost(url);
try {
System.out.println("str[0]:" + str[0]);
StringEntity s = new StringEntity(str[0], "utf-8");
s.setContentType("application/json");
post.setEntity(s);
HttpResponse res = client.execute(post);
HttpEntity entity = res.getEntity();
String contentString = EntityUtils.toString(entity, "utf-8");
System.out.println("contentString:" + contentString);
JSONObject json = new JSONObject(contentString);
//输出返回消息
String media_id = "";
media_id = json.getString("media_id");
if (StringUtils.isNotBlank(media_id)) {
/**
*图文消息群发
* 官方接口文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html
*/
String sendAllMessageUrl = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall";
String url_send = sendAllMessageUrl + "?access_token=" + token;
String str_send = "{\"filter\":{\"is_to_all\":true},\"mpnews\":{\"media_id\":\"" + media_id + "\"},\"msgtype\":\"mpnews\"}";
post(url_send, str_send, "application/json");
}
} catch (Exception e) {
e.printStackTrace();
}
}
} private String post(String url, String json, String contentType) {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
HttpPost post = new HttpPost(url);
try {
StringEntity s = new StringEntity(json, "utf-8");
if (StringUtils.isBlank(contentType)) {
s.setContentType("application/json");
}
s.setContentType(contentType);
post.setEntity(s);
HttpResponse res = client.execute(post);
HttpEntity entity = res.getEntity();
String str = EntityUtils.toString(entity, "utf-8");
return str;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* @param token
* @param beans
* @return
*/
private String[] articalUpload(String token, Content[] beans) {
Integer count = 0;
String str = "{\"articles\":[";
for (int i = 0; i < beans.length; i++) {
//将富文本图片先上传到微信服务器上
String txt = contentHtmlProc(token, beans[i].getHtml());
String mediaId = "";
if (!StringUtils.isBlank("文章类型图")) {
String typeImg = "文章类型图";
mediaId = uploadFile(token, typeImg, "image");
System.out.println("typeImg:" + typeImg);
str = str + "{" +
"\"thumb_media_id\":\"" + mediaId + "\"," +
"\"author\":\"" + beans[i].getAuthor() + "\"," +
"\"title\":\"" + beans[i].getTitle() + "\"," +
"\"content_source_url\":\"" + beans[i].getSourceUrl() + "\"," +
"\"content\":\"" + txt + "\"," +
"\"digest\":\"" + beans[i].getDescription() + "\","
+ "\"show_cover_pic\":\"0\"" + "}";
if (i != beans.length - 1) {
str = str + ",";
}
count++;
}
}
str = str + "]}";
String[] result = new String[2];
result[0] = str;
result[1] = count.toString();
return result;
} /**
* 把内容中的图片先上传到微信服务器
*
* @param access_token 微信的access_token
* @param txt 富文本内容 html代码
* @return
*/
private String contentHtmlProc(String access_token, String txt) {
if (StringUtils.isBlank(txt)) {
return "";
} //从富文本的html中提取img图片路径
List<String> imgUrls = getImageSrc(txt);
for (String img : imgUrls) {
//img路径为图片的绝对路径
//上传图片到微信
String imgRealUrl = uploadImg(access_token, img);
if (StringUtils.isNotBlank(imgRealUrl)) {
txt = txt.replace(img, imgRealUrl);
}
}
//html标签双引号需要注意
txt = txt.replaceAll("\"", "\'");
return txt;
} /**
* 文件上传到微信服务器
* 官方接口文档:https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html
*
* @param access_token
* @param filePath 文件路径 ,绝对地址
* @param type 文件类型
* @return
*/
public String uploadFile(String access_token, String filePath, String type) {
String sendGetUrl = "https://api.weixin.qq.com/cgi-bin/media/upload";
String url = sendGetUrl + "?access_token=" + access_token;
String result = null;
String mediaId = "";
FileUpload fileUpload = new FileUpload();
try {
result = fileUpload.uploadFile(url, filePath, type);
System.out.println("result:" + result);
if (result.startsWith("{") && result.contains("media_id")) {
JSONObject json = new JSONObject(result);
mediaId = json.getString("media_id");
}
} catch (Exception e) {
e.printStackTrace();
}
return mediaId;
} /**
* 把本地图片先上传到服务器 ,上传图文消息内的图片获取URL
* 官网接口地址 :https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Adding_Permanent_Assets.html
*
* @param access_token
* @param filePath 图片路径
* @return
*/
private String uploadImg(String access_token, String filePath) {
String sendGetUrl = "https://api.weixin.qq.com/cgi-bin/media/uploadimg";
String url = sendGetUrl + "?access_token=" + access_token;
String result = null;
String mediaId = "";
FileUpload fileUpload = new FileUpload();
try {
result = fileUpload.uploadFile(url, filePath, null);
if (result.startsWith("{")) {
JSONObject json = new JSONObject(result);
mediaId = json.getString("url");
}
} catch (Exception e) {
e.printStackTrace();
}
return mediaId;
} /**
* 提取img图片路径
*
* @param htmlCode html代码
* @return
*/
public static List<String> getImageSrc(String htmlCode) {
List<String> imageSrcList = new ArrayList<String>();
String regular = "<img(.*?)src=\"(.*?)\"";
String img_pre = "(?i)<img(.*?)src=\"";
String img_sub = "\"";
Pattern p = Pattern.compile(regular, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(htmlCode);
String src = null;
while (m.find()) {
src = m.group();
src = src.replaceAll(img_pre, "").replaceAll(img_sub, "").trim();
imageSrcList.add(src);
}
return imageSrcList;
} /**
* 获取access_token
*
* @return
*/
public String getToken() {
String tokenGetUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";//微信提供获取access_token接口地址
String appid = "";
String secret = ""; System.out.println("~~~~~appid:" + appid);
System.out.println("~~~~~secret:" + secret);
JSONObject tokenJson = new JSONObject();
if (StringUtils.isNotBlank(appid) && StringUtils.isNotBlank(secret)) {
tokenGetUrl += "&appid=" + appid + "&secret=" + secret;
tokenJson = getUrlResponse(tokenGetUrl);
System.out.println("~~~~~tokenJson:" + tokenJson.toString());
try {
return (String) tokenJson.get("access_token");
} catch (JSONException e) {
System.out.println("报错了");
return null;
}
} else {
System.out.println("appid和secret为空");
return null;
}
} private JSONObject getUrlResponse(String url) {
CharsetHandler handler = new CharsetHandler("UTF-8");
try {
HttpGet httpget = new HttpGet(new URI(url));
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
return new JSONObject(client.execute(httpget, handler));
} catch (Exception e) {
e.printStackTrace();
return null;
}
} private static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLSv1");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[]{"TLSv1"}, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
return httpclient; } catch (Exception ex) {
return null;
}
} private class CharsetHandler implements ResponseHandler<String> {
private String charset; public CharsetHandler(String charset) {
this.charset = charset;
} public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if (entity != null) {
if (!StringUtils.isBlank(charset)) {
return EntityUtils.toString(entity, charset);
} else {
return EntityUtils.toString(entity);
}
} else {
return null;
}
} }
}

  

 
Content.java
package com.weixin.sendmessage;

/**
* 内容实体类
*/
public class Content { private Integer id; private String author; private String html; private String title; private String description; private String sourceUrl; public String getSourceUrl() {
return sourceUrl;
} public void setSourceUrl(String sourceUrl) {
this.sourceUrl = sourceUrl;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getAuthor() {
return author;
} public void setAuthor(String author) {
this.author = author;
} public String getHtml() {
return html;
} public void setHtml(String html) {
this.html = html;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
}
}

  

FileUpload.java
package com.weixin.sendmessage;

import org.apache.commons.lang.StringUtils;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL; public class FileUpload {
/**
* 模拟form表单的形式 ,上传文件 以输出流的形式把文件写入到url中,然后用输入流来获取url的响应
*
* @param url 请求地址 form表单url地址
* @param filePath 文件在服务器保存路径
* @return String 正确上传返回media_id
* @throws IOException
*/ /** 微信上传文件接口 */
public String uploadFile(String url, String filePath, String type) throws Exception {
File file = new File(filePath);
String result = null;
if (!file.exists() || !file.isFile()) {
return "文件路径错误";
}
/**
* 第一部分
*/
if(StringUtils.isNotBlank(type)){
url = url+"&type="+type;
}
URL urlObj = new URL(url);
HttpURLConnection con = null; //解决HTTPS
trustAllHttpsCertificates();
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
con=(HttpURLConnection) urlObj.openConnection(); /**
* 设置关键值
*/
con.setRequestMethod("POST"); // 以Post方式提交表单,默认get方式
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); //con.setRequestProperty("Content-Type", "multipart/mixed; boundary=" + BOUNDARY);
//con.setRequestProperty("content-type", "text/html");
// 请求正文信息 // 第一部分:
StringBuilder sb = new StringBuilder();
sb.append("--"); // ////////必须多两道线
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data;name=\"file\";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); // 文件正文部分
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();
/**
* 读取服务器响应,必须读取,否则提交不成功
*/
// con.getResponseCode(); /**
* 下面的方式读取也是可以的
*/ try { // 定义BufferedReader输入流来读取URL的响应
StringBuffer buffer = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(
con.getInputStream(),"UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
//System.out.println(line);
buffer.append(line);
}
if(result==null){
result = buffer.toString();
}
return buffer.toString();
} catch (Exception e) {
System.out.println("发送POST请求出现异常!" + e);
e.printStackTrace();
}
return result;
} private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
} static class miTM implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
} public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
} public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
} public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
} public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
} public static void main(String[] args) throws Exception {
String filePath = "d:/mv1.jpg";
String token="Jdr_B5dQzbWlmmTAlMxbpOZiUfe100laWKeNjRgqfYAJ2GkgCdbQCQO4gAA6e0qd7uYM8fhhzx9ehQBCHlQvKQ";
String result = null;
FileUpload fileUpload = new FileUpload();
result = fileUpload.uploadFile(token, filePath, "image");
System.out.println(result);
}
}

  

JAVA微信公众号网页开发——将文章群发到微信公众号中(文章使用富文本,包含图片)的更多相关文章

  1. 微信公众平台网页开发实战--3.利用JSSDK在网页中获取地理位置(HTML5+jQuery)

    复制一份JSSDK环境,创建一份index.html文件,结构如图7.1所示. 图7.1  7.1节文件结构 在location.js中,封装“getLocation”接口,如下: 01 wxJSSD ...

  2. 在微信小程序中使用富文本转化插件wxParse

    在微信小程序中我们往往需要展示一些丰富的页面内容,包括图片.文本等,基本上要求能够解析常规的HTML最好,由于微信的视图标签和HTML标签不一样,但是也有相对应的关系,因此有人把HTML转换做成了一个 ...

  3. JAVA微信公众号网页开发——将接收的消息转发到微信自带的客服系统

    如果公众号处于开发模式,普通微信用户向公众号发消息时,微信服务器会先将消息POST到开发者填写的url上,无法直接推送给微信自带的客服功能.如果需要把用户推送的普通消息推送到客服功能中,就需要进行代码 ...

  4. C#开发微信公众号——网页开发之微信网页授权

    首先咱们先看下公众号的文档里面的介绍 上述图片的文字描述就是讲述了网页授权有什么用,就是为了获取微信用户的基本信息:授权回调域名的规范,说到域名回调的事情就不得不提一下设置网页授权域名 最好将这三个域 ...

  5. 微信iOS WKWebview 网页开发适配指南

    微信iOS客户端将于2017年3月1日前逐步升级为WKWebview内核,需要网页开发者提前做好网站的兼容检查和适配. 背景 WKWebView 是苹果在iOS 8中引入的新组件,目的是提供一个现代的 ...

  6. 微信公众号网页开发-jssdk config配置参数生成(Java版)

    一.配置参数 参考官方文档:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&la ...

  7. JAVA微信公众号网页开发 —— 用户授权获取openid

    官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 HttpClientUtil.java packa ...

  8. JAVA微信公众号网页开发 —— 接收微信服务器发送的消息

    WeixinMessage.java package com.test; import java.io.Serializable; /** * This is an object that conta ...

  9. JAVA微信公众号网页开发——通过接收人的openid发送模板消息

    TemplateData.java 1 package com.weixin.weixin.template; 2 3 public class TemplateData { 4 private St ...

随机推荐

  1. 洛谷 P4183 - [USACO18JAN]Cow at Large P(点分治)

    洛谷题面传送门 点分治 hot tea. 首先考虑什么样的点能够对以 \(u\) 为根的答案产生 \(1\) 的贡献.我们考虑以 \(u\) 为根对整棵树进行一遍 DFS.那么对于一个点 \(v\), ...

  2. LOJ 3399 -「2020-2021 集训队作业」Communication Network(推式子+组合意义+树形 DP)

    题面传送门 一道推式子题. 首先列出柿子,\(ans=\sum\limits_{T_2}|T_1\cap T_2|·2^{T_1\cap T_2}\) 这个东西没法直接处理,不过注意到有一个柿子 \( ...

  3. Glib 对 C 函数进行单元测试

    1. Glib 单元测试框架 Glib 为单元测试提供了一套完整的测试框架,每个测试运行包括以下几个部分 测试数据结构 测试 setup 与 teardown 函数 测试函数 2. 单元测试数据结构 ...

  4. 到底什么是自动化优先思维?与RPA有什么关系?

    基于RPA的自动化优先,正在成为广大组织的主流管理思维 到底什么是自动化优先思维?与RPA有什么关系? 如何用RPA简单快速的打造一个自动化优先的组织? 文/王吉伟 在IT运维项目中,组织经常会遇到先 ...

  5. eclipse上点击open Perspective找不到java EE的解决办法

    原因:没有安装java ee等插件 Help--->Install New software---->work  with中选择All Available  Sites---->  ...

  6. 数据库ER图基础概念

    ER图分为实体.属性.关系三个核心部分.实体是长方形体现,而属性则是椭圆形,关系为菱形. ER图的实体(entity)即数据模型中的数据对象,例如人.学生.音乐都可以作为一个数据对象,用长方体来表示, ...

  7. web端 - 返回上一步,点击返回,跳转上个页面 JS

    1.方法一: <script language="javascript" type="text/javascript"> window.locati ...

  8. springmvc中拦截器的定义和配置

    package com.hope.interceptor;import org.springframework.lang.Nullable;import org.springframework.web ...

  9. JSP中session、cookie和application的使用

    一.session (单用户使用) 1.用处:注册成功后自动登录,登录后记住用户状态等 使用会话对象session实现,一次会话就是一次浏览器和服务器之间的通话,会话可以在多次请求中保存和使用数据. ...

  10. Django auth

    auth是django一个自带的用户验证系统,使用它可以减少我们的开发流程. 基本使用 大体流程: 自定义类 from django.contrib.auth.models import Abstra ...