Java 实现关注微信公众号动态获取验证码

大家好,我是程序猿小张

前言

个人博客今天上线一个文章私密的功能,该功能需要通过关注公众号来获取验证码,通过正确的验证码才能来查阅文章,具体效果如下图。
在这里插入图片描述
在这里插入图片描述
我感觉还蛮有意思的就决定把这个写出来,供大家去使用,下面来讲讲我的具体实现。

一、首先需要自行前往微信公众平台创建公众号(博主已经有公众号就不在进行讲解这一步了)

二、 在公众号平台选择基础配置进行服务器的配置,如下图

在这里插入图片描述

  • url:填写你后端的接口地址,get请求
  • token:自己随便定义一个
  • EncodingAESKey:可以自己选择也可以随机生成
  • 加解密方式:根据自己的实际情况来选择

三、controller层代码

 @ApiOperation("微信公众号服务器配置校验token")
    @RequestMapping(value = "/test",method = RequestMethod.GET)
    public void checkToken(HttpServletRequest request, HttpServletResponse response) {
        //token验证代码段
        try {
            log.info("请求已到达,开始校验token");
            if (StringUtils.isNotBlank(request.getParameter("signature"))) {
                String signature = request.getParameter("signature");
                String timestamp = request.getParameter("timestamp");
                String nonce = request.getParameter("nonce");
                String echostr = request.getParameter("echostr");
                log.info("signature[{}], timestamp[{}], nonce[{}], echostr[{}]", signature, timestamp, nonce, echostr);
                if (WeChatUtil.checkSignature(signature, timestamp, nonce)) {
                    log.info("数据源为微信后台,将echostr[{}]返回!", echostr);
                    BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                    out.write(echostr.getBytes());
                    out.flush();
                    out.close();
                }
            }
        } catch (IOException e) {
            log.error("校验出错");
            e.printStackTrace();
        }
    }

四、.WeChatUtil代码,需要注意此类里面的token需要与公众号平台填写的token一致

private static String token = "demo123456";

    private static final Logger LOGGER = LoggerFactory.getLogger(WeChatUtil.class);

    /**
     * 校验签名
     * @param signature 签名
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @return 布尔值
     */
    public static boolean checkSignature(String signature,String timestamp,String nonce){
        String checktext = null;
        if (null != signature) {
            //对ToKen,timestamp,nonce 按字典排序
            String[] paramArr = new String[]{token,timestamp,nonce};
            Arrays.sort(paramArr);
            //将排序后的结果拼成一个字符串
            String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);

            try {
                MessageDigest md = MessageDigest.getInstance("SHA-1");
                //对接后的字符串进行sha1加密
                byte[] digest = md.digest(content.getBytes());
                checktext = byteToStr(digest);
            } catch (NoSuchAlgorithmException e){
                e.printStackTrace();
            }
        }
        //将加密后的字符串与signature进行对比
        return checktext !=null ? checktext.equals(signature.toUpperCase()) : false;
    }

    /**
     * 将字节数组转化我16进制字符串
     * @param byteArrays 字符数组
     * @return 字符串
     */
    private static String byteToStr(byte[] byteArrays){
        String str = "";
        for (int i = 0; i < byteArrays.length; i++) {
            str += byteToHexStr(byteArrays[i]);
        }
        return str;
    }

    /**
     *  将字节转化为十六进制字符串
     * @param myByte 字节
     * @return 字符串
     */
    private static String byteToHexStr(byte myByte) {
        char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        char[] tampArr = new char[2];
        tampArr[0] = Digit[(myByte >>> 4) & 0X0F];
        tampArr[1] = Digit[myByte & 0X0F];
        String str = new String(tampArr);
        return str;
    }

需要注意在公众号平台提交服务器配置时这些代码需要部署上线,否则会token失效。以上代码可直接复制,经过博主测试不会存在token失效问题。下面讲一下如何通过关键词来实现自动回复功能

五、pom.xml引入依赖

  		<dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.3</version>
        </dependency>

六、同样的是controller层添加如下代码

@ApiOperation("处理微信服务器的消息转发")
    @PostMapping(value = "test")
    public String  wechat(HttpServletRequest request) throws Exception {
        // 调用parseXml方法解析请求消息
        Map<String,String> requestMap = WeChatUtil.parseXml(request);
        // 消息类型
        String msgType = requestMap.get("MsgType");
        // xml格式的消息数据
        String respXml = null;
        String mes = requestMap.get("Content");
        // 文本消息
        if ("text".equals(msgType) && "验证码".equals(mes)) {
            String code = RanDomUtil.generationNumber(6);
            respXml=WeChatUtil.sendTextMsg(requestMap,code);
            redisCache.setCacheObject(RedisConstants.WECHAT_CODE+code,code,30, TimeUnit.MINUTES);
        }
        return respXml;
    }

此处需要注意 此接口和前面校验token的接口请求方式不同,这里是post请求,前面校验token是get请求,这里的接口地址不能乱写,需要和公众号平台填写的url相同,也就是前面校验token和这里接收请求的接口一致,只是请求方式不同

七、WeChatUtil添加如下代码

 /**
     * 解析微信发来的请求(xml)
     *
     * @param request
     * @return
     * @throws Exception
     */
    public static Map<String,String> parseXml(HttpServletRequest request) throws Exception {
        LOGGER.info("请求已到达,开始解析参数...");

        // 将解析结果存储在HashMap中
        Map<String,String> map = new HashMap<>();

        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();
        // 遍历所有子节点
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }

        // 释放资源
        inputStream.close();
        LOGGER.info("参数解析完成。{}",map);
        return map;
    }
    /**
     * 回复文本消息
     * @param requestMap
     * @param content
     * @return
     */
    public static String sendTextMsg(Map<String,String> requestMap,String content){

        Map<String,Object> map= new HashMap<>();
        map.put("ToUserName", requestMap.get("FromUserName"));
        map.put("FromUserName",  requestMap.get("ToUserName"));
        map.put("MsgType", "text");
        map.put("CreateTime", new Date().getTime());
        map.put("Content", content);
        return  mapToXML(map);
    }
    public static String mapToXML(Map map) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        mapToXML2(map, sb);
        sb.append("</xml>");
        LOGGER.info("请求完成,返回参数:{}",sb);
        try {
            return sb.toString();
        } catch (Exception e) {
        }
        return null;
    }
    private static void mapToXML2(Map map, StringBuffer sb) {
        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);
                sb.append("<" + key + ">");
                for (int i = 0; i < list.size(); i++) {
                    HashMap hm = (HashMap) list.get(i);
                    mapToXML2(hm, sb);
                }
                sb.append("</" + key + ">");

            } else {
                if (value instanceof HashMap) {
                    sb.append("<" + key + ">");
                    mapToXML2((HashMap) value, sb);
                    sb.append("</" + key + ">");
                } else {
                    sb.append("<" + key + "><![CDATA[" + value + "]]></" + key + ">");
                }

            }

        }
    }

OK,大功告成,以上只是讲解了自动回复文本类型的功能,其他类型功能以后在进行讲解或可自行百度 最后献上完成的示例图
在这里插入图片描述
Bye~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 要获取微信公众号的code,需要使用Java编程语言微信公众号开发接口。以下是详细步骤: 第一步,通过微信官方网站注册一个公众号,并在开发者中心中下载微信公众号的SDK。 第二步,使用Java进行开发,编写相应的代码,实现接收微信公众平台的消息、回复微信公众平台的消息等功能。同时,在代码中需要配置微信公众平台的各种参数,例如APPID、APPSECRET、SIGNATURE等。 第三步,通过调用微信公众平台提供的接口获取微信公众号的code。 在Java代码中,可以使用HttpClient这个类库来请求微信公众平台提供的获取code的接口,然后通过解析返回的json数据,获取到相应的code。 最后,获取到code之后,可以使用该code来获取access_token等重要信息,在公众号开发中应用。通过这些方法,可以成功获取微信公众号的code,进而实现更加多样化的公众号开发。 ### 回答2: Java 获取微信公众号code 的方法有以下两种: 1. 使用微信官方提供的开发接口 微信官方提供了开发者工具包 Weixin-java-tools,其中包含了获取微信公众号code 的方法。 具体步骤如下: a. 在 pom.xml 文件中引入 Weixin-java-tools 工具包: ```xml <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-tools</artifactId> <version>3.4.0</version> </dependency> ``` b. 在代码中调用 Weixin-java-tools 中的方法实现获取 code: ```java public String getCode() throws WxErrorException { WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(wxMpInMemoryConfigStorage); String redirectUrl = wxMpService.oauth2buildAuthorizationUrl( "http://example.com/wx/oauth/callback", WxConsts.OAuth2Scope.SNSAPI_USERINFO, null); return redirectUrl; } ``` 2. 使用第三方开源库 除了使用微信官方提供的工具包外,还有第三方开源库 WeChat-Java-SDK,也可以实现获取微信公众号 code。 具体步骤如下: a. 在 pom.xml 文件中引入 WeChat-Java-SDK 工具包: ```xml <dependency> <groupId>com.github.sd4324530</groupId> <artifactId>wechat-java-sdk</artifactId> <version>1.3.8.2</version> </dependency> ``` b. 在代码中调用 WeChat-Java-SDK 中的方法实现获取 code: ```java public String getCode() { WeChat weChat = new WeChat(config); String redirectUrl = weChat.getOpenOauthUrl(WxConsts.OAuth2Scope.SNSAPI_USERINFO, callbackUrl, null); return redirectUrl; } ``` 以上就是 Java 获取微信公众号 code 的两种方法,开发者可以根据自己的需求选择相应的方法。 ### 回答3: 在 Java获取微信公众号 code 通常涉及到两个主要步骤,首先是在前端页面中获取 code,然后是使用 Java 后端将 code 传递给微信服务器进行验证,最终获得用户信息。 第一步,前端页面中获取 code 在前端页面中获取微信公众号 code 可以通过使用微信官方提供的 JS-SDK 来实现。首先需要在页面引入 JS-SDK,然后使用微信提供的方法获取 code。其中,获取 code 的过程需要用户在微信客户端内打开并登录公众号,否则获取 code 会失败。 以下是获取 code 的示例代码: ```javascript $.ajax({ type: 'GET', url: 'https://open.weixin.qq.com/connect/oauth2/authorize?appid={APPID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect', dataType: 'json', success: function (data) { var code = data.code; console.log(code); }, error: function (xhr, errorType, error) { console.log(error); } }); ``` 在以上代码中,{APPID} 是公众号的 AppID,{REDIRECT_URI} 指定了用户授权后重定向的页面路径。获取到的 code 可以通过 AJAX 请求发送到后端进行验证。 第二步,使用 Java 后端将 code 传递给微信服务器进行验证 在 Java 后端中,我们可以通过使用 Spring 框架提供的 RestTemplate 类进行 HTTP 请求。同样需要注意的是,在进行 HTTP 请求之前需要在公众号后台配置安全域名,否则会出现请求失败的情况。 以下是使用 RestTemplate 类进行 HTTP 请求的示例代码: ```java RestTemplate restTemplate = new RestTemplate(); String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={APPID}&secret={SECRET}&code={CODE}&grant_type=authorization_code"; String appId = "****"; // 公众号的 AppID String secret = "****"; // 公众号的 AppSecret String code = "****"; // 前端获取到的 code String result = restTemplate.getForObject(url, String.class, appId, secret, code); System.out.println(result); ``` 以上代码中,url 指定了微信接口的地址和参数,其中 appId、secret 和 code 分别是公众号的 AppID、AppSecret 和前端获取到的 code。getForObject() 方法用于发送 HTTP GET 请求,并返回接口返回的字符串结果。 最终,我们可以通过解析微信接口返回的 JSON 字符串,获取用户的 openid、access_token 等信息。获取到用户信息后,我们可以将其存储到数据库中,或者再次发送 HTTP 请求获取更多信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿小张丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值