[Simple] Java implements WeChat official account message template push, [Solution] WeChat official account message push reports 47001 error code, message push request header sets application/json and reports error 47001

foreword

Using java to implement official account message template push has been successfully tested.
Recommendation: Personally, I recommend implementation method 1, because it is simple and concise, just use hutool, and generally projects now have this tool introduced; method 2 is relatively primitive and has a lot of code.
Solution: Use the following method to return ok without error codes such as 44002/47001.

renderings

insert image description here

Prepare template

Official website of WeChat public account platform: https://mp.weixin.qq.com/cgi-bin/loginpage
insert image description here
For details of clicking on the template, you can refer to the corresponding fields to fill in
insert image description here

Java implementation

The following implementation methods are generally related to the code
common-dependency

	<!-- 阿里巴巴json依赖包-->
	<dependency>
	    <groupId>com.alibaba</groupId>
	    <artifactId>fastjson</artifactId>
	    <version>1.1.41</version>
	</dependency>

general-code

    /**
     * 给返回消息模板文字上色(但是:2023-05-04 取消了自定义文字颜色)
     * @param value
     * @return
     */
    public JSONObject getJson(String value) {
    
    
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("value", value);
        jsonObject.put("color", "#173177");
        return jsonObject;
    }

Implementation one (recommended)

Use the hutool tool to request a call

	<!-- hutool工具 -->
	<dependency>
	    <groupId>cn.hutool</groupId>
	    <artifactId>hutool-all</artifactId>
	    <version>5.7.7</version>
	</dependency>

quote

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;

accomplish

	public void sendMsg() {
    
    
	
	    JSONObject obj = new JSONObject();
	    obj.put("touser", ""); // 用户微信openId
	    obj.put("template_id", ""); // 消息模板ID
	    obj.put("url", ""); // 点击详情跳转的路径
	
	    JSONObject data = new JSONObject();
	    data.put("first", new JSONObject()); // {
    
    {first.DATA}} 如:您有一条通知(但是:2023-05-04 取消了这一行显示)
	    data.put("keyword1", getJson("张三")); // {
    
    {keyword1.DATA}} 1~5都是对应模板上面的
	    data.put("keyword2", new JSONObject()); // ....
	    data.put("keyword3", new JSONObject());
	    data.put("keyword4", new JSONObject());
	    data.put("keyword5", new JSONObject());
	    data.put("remark", new JSONObject());// {
    
    {remark.DATA}} 如:备注(但是:2023-05-04 取消了这一行显示)
	
	    obj.put("data", data);
	
	    String tk= ""; // 参考官网微信公众号token获取:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
	    // 如token获取路径(get请求两个参数):https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret
		// 这两个参数appId和secret在:公众号平台->设置与开发->基本配置 中可以看到
		
	    String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + tk;
	    String result = HttpRequest.post(url).body(obj.toString(), "application/json;charset=UTF-8").timeout(100000).execute().body();
	
	    JSONObject resultObject = JSONObject.parseObject(result);
	    Integer code = resultObject.getInteger("errcode");
	    int errcode = code == null ? -1 : code;
	    if (errcode == 0) {
    
    // 消息发送成功,看是否记录推送记录
	        System.out.println("推送成功");
	    } else{
    
    
	        System.out.println("推送失败");
	    }
	}

Method 2 (not recommended)

Use apache.http.client dependency

	<!-- httpclient依赖 -->
	<dependency>
	    <groupId>org.apache.httpcomponents</groupId>
	    <artifactId>httpclient</artifactId>
	</dependency>
	<!-- httpclient缓存 -->
	<dependency>
	    <groupId>org.apache.httpcomponents</groupId>
	    <artifactId>httpclient-cache</artifactId>
	</dependency>

quote

import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;

accomplish

public void sendMsg() {
    
    

        JSONObject obj = new JSONObject();
        obj.put("touser", ""); // 用户微信openId
        obj.put("template_id", ""); // 消息模板ID
        obj.put("url", ""); // 点击详情跳转的路径

        JSONObject data = new JSONObject();
        data.put("first", new JSONObject()); // {
    
    {first.DATA}} 如:您有一条通知(但是:2023-05-04 取消了这一行显示)
        data.put("keyword1", getJson("张三")); // {
    
    {keyword1.DATA}} 1~5都是对应模板上面的
        data.put("keyword2", new JSONObject()); // ....
        data.put("keyword3", new JSONObject());
        data.put("keyword4", new JSONObject());
        data.put("keyword5", new JSONObject());
        data.put("remark", new JSONObject());// {
    
    {remark.DATA}} 如:备注(但是:2023-05-04 取消了这一行显示)

        obj.put("data", data);

        String tk= ""; // 参考官网微信公众号token获取:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
        // 如token获取路径(get请求两个参数):https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret
        // 这两个参数appId和secret在:公众号平台->设置与开发->基本配置 中可以看到

        HttpPost httpost = new HttpPost("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + tk);
        MyHttpUtil http = new MyHttpUtil();
        StringEntity entity = new StringEntity(obj.toString(), "UTF-8");
        httpost.setEntity(entity);
        String result = http.postHttp(httpost);// 返回的结果

        JSONObject resultObject = JSONObject.parseObject(result);
        Integer code = resultObject.getInteger("errcode");
        int errcode = code == null ? -1 : code;
        if (errcode == 0) {
    
    // 消息发送成功,看是否记录推送记录
            System.out.println("推送成功");
        } else{
    
    
            System.out.println("推送失败");
        }
    }

Among them, MyHttpUtil is encapsulated by itself, as follows

package com.common.util;

import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

@SuppressWarnings("deprecation")
public class MyHttpUtil {
    
    

    private DefaultHttpClient httpclient = new DefaultHttpClient(new ThreadSafeClientConnManager());
    private HttpResponse response;

    public MyHttpUtil() {
    
    
        super();
        httpclient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));
    }

    /**
     * 发送get请求,返回界面代码
     *
     * @param url
     * @return
     */
    public String getHttp(String url) {
    
    
        HttpGet get = new HttpGet(url);
        String result = "";
        try {
    
    
            response = httpclient.execute(get);
            httpclient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
            httpclient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);
            int statusCode = response.getStatusLine().getStatusCode();//
            if (statusCode == HttpStatus.SC_OK) {
    
    
                result = EntityUtils.toString(response.getEntity());
            } else {
    
    
                result = "返回码:" + statusCode;
            }
        } catch (ClientProtocolException e) {
    
    
            e.printStackTrace();
            get.abort();
        } catch (IOException e) {
    
    
            e.printStackTrace();
            get.abort();
        } finally {
    
    
            get.abort();
        }
        return result;
    }

    /**
     * 发送get请求,返回界面代码
     *
     * @return
     */
    public String postHttp(HttpPost httpost) {
    
    
        String result = "";
        try {
    
    
            httpclient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
            httpclient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);
            response = httpclient.execute(httpost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
    
    
                result = EntityUtils.toString(response.getEntity());
            } else {
    
    
                result = "返回码:" + statusCode;
            }
        } catch (ClientProtocolException e) {
    
    
            e.printStackTrace();
            httpost.abort();
        } catch (IOException e) {
    
    
            e.printStackTrace();
            httpost.abort();
        } finally {
    
    
            httpost.abort();
        }
        return result;
    }

    /**
     * 设置浏览器的状态(必须带上)
     */
    public HttpPost setPostHeader(HttpPost httpost, String Referer) {
    
    
        // 必须模拟浏览器的配置,不然登录无效
        httpost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:48.0) Gecko/20100101 Firefox/48.0");
        httpost.setHeader("Origin", "http://www.baidu.com");
        httpost.setHeader("Cache-Control", "max-age=0");
        httpost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        httpost.setHeader("Accept-Encoding", "gzip,deflate");
        httpost.setHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
        httpost.setHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
        httpost.setHeader("Referer", "www.baidu.com");
        httpost.setHeader("Host", "www.baidu.com");
        return httpost;
    }

    /**
     * 发送get请求, 下载文件存储
     *
     * @param url
     * @return
     */
    public String downFile(String url, String filePath, String fileName) {
    
    
        HttpGet get = new HttpGet(url);
        String result = "";
        try {
    
    
            response = httpclient.execute(get);
            httpclient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
            httpclient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
    
    
                HttpEntity entity = response.getEntity();
                InputStream is = entity.getContent();
                if (fileName.equals("")) {
    
    
                    fileName = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + getFileName(response);
                }
                saveToFile(filePath + "/" + fileName, is);
                if (entity != null) {
    
    
                    entity.consumeContent();
                }
                if (new File(filePath + "/" + fileName).exists()) {
    
    
                    result = fileName;
                }
            }
        } catch (ClientProtocolException e) {
    
    
            e.printStackTrace();
            get.abort();
        } catch (IOException e) {
    
    
            e.printStackTrace();
            get.abort();
        } finally {
    
    
            get.abort();
        }
        return result;
    }

    public static boolean saveToFile(String fileDir, InputStream input) {
    
    
        File file = new File(fileDir);
        FileOutputStream output;
        try {
    
    
            output = new FileOutputStream(file);
            byte b[] = new byte[1024];
            int j = 0;
            while ((j = input.read(b)) != -1) {
    
    
                output.write(b, 0, j);
            }
            output.flush();
            output.close();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
            return false;
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return false;
        } finally {
    
    
            try {
    
    
                input.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        return true;

    }

    /**
     * 5. 获取response header中Content-Disposition中的filename值
     *
     * @param response 响应
     * @return String
     * @desc :
     */
    public static String getFileName(HttpResponse response) {
    
    
        Header contentHeader = response.getFirstHeader("Content-Disposition");
        String filename = null;
        if (contentHeader != null) {
    
    
            HeaderElement[] values = contentHeader.getElements();
            if (values.length == 1) {
    
    
                NameValuePair param = values[0].getParameterByName("filename");
                if (param != null) {
    
    
                    try {
    
    
//						filename = new String(param.getValue().toString().getBytes(), "utf-8");
//						filename = URLDecoder.decode(param.getValue(), "utf-8");
                        String fname = param.getValue();
                        filename = fname.substring(fname.lastIndexOf("."), fname.length());
                    } catch (Exception e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        }
        return filename;
    }

}

The above is the realization of WeChat official account message push!

Guess you like

Origin blog.csdn.net/weixin_43992507/article/details/130615657