栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【微信公众号后台基础能力接口对接】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【微信公众号后台基础能力接口对接】

微信公众号后台基础能力接口

说明

步骤后台代码

maven消息接收接口类帮助类实体类 结尾

说明

本文主要是对接公众号的基础能接口
消息自动回复
用户信息事件
模板消息推送

步骤

1.申请公众号
2.进入公众号后台 获取 appid 和 secret
3.设置微信公众号后台接口地址,与关注用户的互动都会发到这个地址

后台代码 maven

            org.springframework.boot
            spring-boot-starter-web
        

        
            cn.hutool
            hutool-all
            5.4.1
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.projectlombok
            lombok
        

        
        
            org.springframework.boot
            spring-boot-devtools
            true
            true
        

        
            commons-io
            commons-io
            2.3
        

        
        
            com.alibaba
            fastjson
            1.2.59
        

        
            dom4j
            dom4j
            1.6.1
        
消息接收

将服务器地址设置为http:xxx/mainCall
将自己ip设为在白名单里面
将token 设置 与CheckUtil 一致
废话少说 上代码

//接收微信消息接口
@RestController
public class WxCallBackApi {

    @Autowired
    WxSubscription wxSubscription;

    @RequestMapping("/mainCall")
    public void mainCall(HttpServletRequest request, HttpServletResponse response){
        try {
            Signature sg = new Signature(
                    request.getParameter("signature"),
                    request.getParameter("timestamp"),
                    request.getParameter("nonce"),
                    request.getParameter("echostr"));
            String method = request.getMethod();

            // 配置服务器域名 回调地址时 会发送一条验证消息 是GET请求
            if ("GET".equals(method)) {
                if (sg != null && CheckUtil.checkSignature(sg)) {
                    wxSubscription.reply(response,sg.getEchostr());
                }
            }
            // 后续如果公众号收到用户消息 各种事件 是POST请求
            if ("POST".equals(method)) {
                if (CheckUtil.checkSignature(sg)) {
                    wxSubscription.callWeChatMessage(request,response);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
    }
}
接口类
@Slf4j
@EnableScheduling
@Component
public class WxSubscription {

    private  final String base_URL = "https://api.weixin.qq.com";

    private  final String URL_TOKEN = base_URL+"/cgi-bin/token";

    private  final String URL_MENU_CREATE = base_URL+"/cgi-bin/menu/create";

    private  final String URL_GET_CURRENT_SELFMENU_INFO = base_URL+"/cgi-bin/get_current_selfmenu_info";

    private  final String URL_MEDIA_UPLOAD = base_URL+"/cgi-bin/media/upload";

    private  final String URL_MEDIA_GET = base_URL+"/cgi-bin/media/get";

    private  final String URL_USER_GET = base_URL+"/cgi-bin/user/get";

    private  final String URL_USER_INFO = base_URL+"/cgi-bin/user/info";

    private  final String URL_TEMPLATE_GET_ALL_PRIVATE_TEMPLATE = base_URL+"/cgi-bin/template/get_all_private_template";

    private  final String URL_MESSAGE_TEMPLATE_SEND= base_URL+"/cgi-bin/message/template/send";

    //获取AccessToken
    public  String getAccessToken(){
        HashMap param = new HashMap();
        param.put("grant_type","client_credential");
        param.put("appid",CheckUtil.appid);
        param.put("secret",CheckUtil.secret);
        String jsonstr = HttpUtil.get(URL_TOKEN,param);
        JSONObject result = JSONObject.parseObject(jsonstr);
        if(StrUtil.isBlank(result.getString("errcode"))){
            return  result.getString("access_token");
        }
        return "";
    }

    //每小时刷新access_token
    @Scheduled(cron = "0 0 1 * * ?")
    @PostConstruct//启动时执行一次
    public  void flushAccessToken(){
        CheckUtil.access_token = getAccessToken();
        log.info("========定期刷新token========{}",CheckUtil.access_token);
    }

    //创建公众号菜单
    //需开启后台配置地址
    //参数参考文档 https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html
    public  boolean createMenu(JSONObject param){
        String validUrl = URL_MENU_CREATE +"?access_token="+CheckUtil.access_token;
        String jsonstr =  HttpUtil.post(validUrl,param.toJSONString());
        JSONObject result = JSONObject.parseObject(jsonstr);
        return returnBoolean(result);
    }

    //获取当前菜单信息
    //参数参考文档 https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Querying_Custom_Menus.html
    public  JSONObject getMenuInfo(){
        String validUrl = URL_GET_CURRENT_SELFMENU_INFO +"?access_token="+CheckUtil.access_token;
        String jsonstr =  HttpUtil.get(validUrl);
        JSONObject result = JSONObject.parseObject(jsonstr);
        if(StrUtil.isBlank(result.getString("errcode"))){
            return  result;
        }
        return null;
    }

    //删除菜单(不常用 懒得写)
    //参数参考文档 https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Deleting_Custom-Defined_Menu.html

    //创建个性化菜单(不常用 懒得写)
    //参数参考文档 https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Personalized_menu_interface.html

    //接收公众用户消息、事件
    public void callWeChatMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            //把微信返回的xml信息转成map
            Map map = XmlUtil.xmlToMap(request);
            //发送方用用户帐号(OpenID)
            String fromUserName = map.get("FromUserName");
            //开发者(公众号)
            String toUserName = map.get("ToUserName");
            //消息类型
            String msgType = map.get("MsgType");
            //消息内容
            String content = map.get("Content");

            String eventType = map.get("Event");
            if(CheckUtil.MSGTYPE_EVENT.equalsIgnoreCase(msgType)){
                //如果为事件类型
                if(CheckUtil.MESSAGE_SUBSCIBE.equalsIgnoreCase(eventType)){
                    //处理关注事件
                    if(StringUtils.isNotEmpty(fromUserName)){
                        //用户信息入库 ybc

                    }
                }else if(CheckUtil.MESSAGE_UNSUBSCIBE.equalsIgnoreCase(eventType)){
                    //处理取消关注事件

                }else if(CheckUtil.MESSAGE_CLICK.equalsIgnoreCase(eventType)){
                    //处理菜单点击事件
                    String EventKey = map.get("EventKey");

                }
            }else if(CheckUtil.MESSAGE_TEXT.equalsIgnoreCase(msgType)){
                //用户发送文字
                //返回文字消息
                //测试
                HashMap param = new HashMap();
                param.put("ToUserName",fromUserName);
                param.put("FromUserName",toUserName);
                param.put("CreateTime","12345678");
                param.put("MsgType",CheckUtil.MESSAGE_TEXT);
                param.put("Content","你好");
                //返回图片消息
//                HashMap param = new HashMap();
//                param.put("ToUserName",fromUserName);
//                param.put("FromUserName",toUserName);
//                param.put("CreateTime","12345678");
//                param.put("MsgType",CheckUtil.MESSAGE_IMAGE);
//                HashMap Image = new HashMap();
//                Image.put("MediaId","2qvNch5UW27Q-6IdwchvMj7XEOihDGo2Myb1o3F1xrELcHEQE90Zjjv9zDQLSmob");//通过上传素材接口返回的id 或直接在微信公众号后台上传
//                param.put("Image",Image);
                //其他类型参考 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html
                reply(response,param);
                return;


            }
            //...其他类型自己加

        } catch (Exception e) {
            e.printStackTrace();

        }
        reply(response,"success");
    }

    //无回复类型
    public void reply(HttpServletResponse response,String str) {
        try {
            response.setCharacterEncoding("UTF-8");
            PrintWriter writer = response.getWriter();
            writer.write(str);
            writer.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //被动回复用户消息
    //参数参考 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html#%E5%9B%9E%E5%A4%8D%E6%96%87%E6%9C%AC%E6%B6%88%E6%81%AF
    public void reply(HttpServletResponse response,Map map)throws Exception{
        XmlUtil.mapToXmlResponse(response,map);
    }

    //新增临时素材
    //参考 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html
    public boolean materialAddNews(String filepath){
        HashMap param = new HashMap();
        param.put("access_token",CheckUtil.access_token);
        param.put("type",CheckUtil.MESSAGE_IMAGE);
        param.put("media", FileUtil.file(filepath));
        String jsonstr = HttpUtil.post(URL_MEDIA_UPLOAD,param);
        JSONObject result = JSONObject.parseObject(jsonstr);
        log.info("请求地址{},返回值{}",URL_MEDIA_UPLOAD,jsonstr);
        return returnBoolean(result);
    }

    //获取临时素材
    //参考 https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Get_temporary_materials.html
    public void mediaDownload(String media_id,String filepath){
        String validUrl = URL_MEDIA_GET+"?access_token="+CheckUtil.access_token+"&media_id="+media_id;
        HttpUtil.downloadFile(validUrl,filepath);
        log.info("请求地址{}",validUrl);
    }

    /
    public static Map xmlToMap(HttpServletRequest request) throws IOException, documentException {
        HashMap map = new HashMap();
        SAXReader reader = new SAXReader();

        InputStream ins = request.getInputStream();
        document doc = reader.read(ins);

        Element root = doc.getRootElement();
        @SuppressWarnings("unchecked")
        List list = (List)root.elements();

        for(Element e:list){
            map.put(e.getName(), e.getText());
        }
        ins.close();
        return map;
    }

    
    public static void mapToXmlResponse(HttpServletResponse response, Map map) throws Exception {
        response.setContentType("text/xml");
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write(mapToXml(map));
        writer.close();
    }

    
    public static String mapToXml(Map map) throws Exception{
        if (null == map) return null;
//        System.out.println("转换前的Map对象数据:" + map.toString());
        StringBuffer sb = new StringBuffer();
        
//        sb.append("");
        sb.append("");
        mapToXmlHelp(map, sb);
        sb.append("");
//        System.out.println("将map转成xml后的数据:" + sb.toString());
        return sb.toString();
    }

    
    private static void mapToXmlHelp(Map map, StringBuffer str) throws Exception{
        Set set = map.keySet();
        
        for (Iterator it = set.iterator(); it.hasNext();) {
            String key = (String) it.next();
            Object value = map.get(key);
            if (null == value)
                value = "";
            
            if (value.getClass().getName().equals("java.util.ArrayList")) {
                ArrayList list = (ArrayList) map.get(key);
                str.append("<" + key + ">");
                for (int i = 0; i < list.size(); i++) {
                    HashMap hm = (HashMap) list.get(i);
                    mapToXmlHelp(hm, str);
                }
                str.append("");
                
                if (null !=list && !list.isEmpty() && list.size() <= 1) {
                    str.append("<" + key + ">");
                    for (int i = 0; i < list.size(); i++) {
                        HashMap hm = (HashMap) list.get(i);
                        mapToXmlHelp(hm, str);
                    }
                    str.append("");
                }
                
            } else {
                if (value instanceof HashMap) {
                    str.append("<" + key + ">");
                    mapToXmlHelp((HashMap) value, str);
                    str.append("");
                } else {
                    str.append("<" + key + ">" + value + "");
                }
            }
        }
    }


}
实体类

Signature

@Data
@NoArgsConstructor                 //无参构造
@AllArgsConstructor
public class Signature {
    private String signature;
    private String timestamp;
    private String nonce;
    private String echostr;
}

结尾

实际上公众号不需要配置后台地址也可以用,如果想与自建系统互动,则可参照上述代码。
写了一下常用接口,代码有点乱,为了方便很多都没分开,如果能给到大佬们一点点帮助,请给我一点点动力,让我相信光
后续将完成更多接口,顺便将返回值JsonObject 用实体类代替哦,代码没什么技术含量,只想用劳动造福社会
gitee地址:https://gitee.com/yangbaocai/wxInterface

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/735413.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号