【简单】Java实现微信公众号消息模板推送,【解决】微信公众号消息推送报47001错误码,消息推送请求头设置application/json 报错47001

前言

使用java实现公众号消息模板推送,都是经过成功测试了的。
推荐:个人比较推荐实现方式一,因为简单简洁就把hutool用起来就行了,而且一般现在项目都有引入这个工具的;方式二的话相对来讲比较原始一点,代码量又多。
解决:如下使用不会出现44002/47001等错误码直接返回ok。

效果图

在这里插入图片描述

准备模板

微信公众号平台官网:https://mp.weixin.qq.com/cgi-bin/loginpage
在这里插入图片描述
点击模板的详情可以参考对应字段填充
在这里插入图片描述

java实现

下面的实现方法通用相关的代码
通用-依赖

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

通用-代码

    /**
     * 给返回消息模板文字上色(但是: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;
    }

实现一(推荐)

使用hutool工具请求调用

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

引用

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

实现

	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("推送失败");
	    }
	}

方式二(不推荐)

使用apache.http.client依赖

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

引用

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

实现

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("推送失败");
        }
    }

其中 MyHttpUtil 是自己封装的,如下

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

}

以上就是微信公众号消息推送的实现了!

猜你喜欢

转载自blog.csdn.net/weixin_43992507/article/details/130615657