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

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);
	}
}

  

猜你喜欢

转载自www.cnblogs.com/pxblog/p/11842328.html