梦里的青蛙 發表於 2019-11-12 15:21:00

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

<p>&nbsp;</p>
<pre>SendTextToAllUserAct.java</pre>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:true;">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;
      for (int i = 0; i &lt; ids.length; i++) {
            beans = contentMng.findById(ids); //查询所有要发送的内容
      }
      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);
      if (contentCount &gt; 0) {
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            //HttpClient
            CloseableHttpClient client = httpClientBuilder.build();
            client = (CloseableHttpClient) wrapClient(client);
            HttpPost post = new HttpPost(url);
            try {
                System.out.println("str:" + str);
                StringEntity s = new StringEntity(str, "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 &lt; beans.length; i++) {
            //将富文本图片先上传到微信服务器上
            String txt = contentHtmlProc(token, beans.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.getAuthor() + "\"," +
                        "\"title\":\"" + beans.getTitle() + "\"," +
                        "\"content_source_url\":\"" + beans.getSourceUrl() + "\"," +
                        "\"content\":\"" + txt + "\"," +
                        "\"digest\":\"" + beans.getDescription() + "\","
                        + "\"show_cover_pic\":\"0\"" + "}";
                if (i != beans.length - 1) {
                  str = str + ",";
                }
                count++;
            }
      }
      str = str + "]}";
      String[] result = new String;
      result = str;
      result = 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&lt;String&gt; 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("{") &amp;&amp; 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&lt;String&gt; getImageSrc(String htmlCode) {
      List&lt;String&gt; imageSrcList = new ArrayList&lt;String&gt;();
      String regular = "&lt;img(.*?)src=\"(.*?)\"";
      String img_pre = "(?i)&lt;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) &amp;&amp; StringUtils.isNotBlank(secret)) {
            tokenGetUrl += "&amp;appid=" + appid + "&amp;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&lt;String&gt; {
      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() &gt;= 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;
            }
      }

    }
}
</pre>
</div>
<p>  </p>
<pre> </pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<pre>Content.java</pre>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:true;">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;
    }
}
</pre>
</div>
<p>  </p>
<pre>FileUpload.java</pre>
<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:true;">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+"&amp;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;
                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;
                javax.net.ssl.TrustManager tm = new miTM();
                trustAllCerts = 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);
        }
}
</pre>
</div>
<p>  </p>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
   



-----------------------有任何问题可以在评论区评论,也可以私信我,我看到的话会进行回复,欢迎大家指教------------------------
                         (蓝奏云官网如果有地址失效了,可以私信我,后续看到会补充)<br><br>
来源:https://www.cnblogs.com/pxblog/p/11842328.html
頁: [1]
查看完整版本: JAVA微信公众号网页开发——将文章群发到微信公众号中(文章使用富文本,包含图片)