关于java对接微信公众号(对接百度AI实现图片文字识别,对接聚合数据实现笑话、谜语大全,成语接龙等功能)

前言:

1.运行效果图

1.1 关注事件

1.2 笑话大全

1.3 谜语大全

1.3 多级菜单

1.4 按钮跳转事件

1.5 心灵鸡汤

1.6 图片文字识别

1.7成语接龙(有点智障)

2.项目结构

3.xml依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.11</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zsh</groupId>
    <artifactId>wx_account1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>wx_account1</name>
    <description>wx_account1</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- DOM4J是 dom4j.org 出品的一个开源XML解析包-->
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.3</version>
        </dependency>
        <!-- XStream是个很强大的工具,能将java对象和xml之间相互转化-->
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.19</version>
        </dependency>

        <!-- 和fastjson作用一样,对json进行解析与构建-->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.2.3</version>
            <classifier>jdk15</classifier>
        </dependency>
        <!-- 引入百度ai的依赖 -->
        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.16.12</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-simple</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>


        <!--httpClient需要的依赖-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <!--//httpclient缓存-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient-cache</artifactId>
            <version>4.5</version>
        </dependency>
        <!--//http的mime类型都在这里面-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.3.2</version>
        </dependency>
        <!-- 随机笑话  -->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.2.3</version>
            <classifier>jdk15</classifier>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

4.工具类

4.1 HttpUtil:http请求工具类

package com.zsh.wx_account1.util;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @Author ZhaoShuHao
 * @Date 2023/8/23 9:35
 */
public class HttpUtil {
    /**
     * get⽅式的http请求
     *
     * @param httpUrl 请求地址
     * @return 返回结果
     */
    public static String doGet(String httpUrl) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;// 返回结果字符串
        try {
            // 创建远程url连接对象
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开⼀个连接,强转成httpURLConnection类
            connection = (HttpURLConnection)
                    url.openConnection();
            // 设置连接⽅式:get
            connection.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);
            // 发送请求
            connection.connect();
            // 通过connection连接,获取输⼊流
            if (connection.getResponseCode() == 200) {
                inputStream = connection.getInputStream();
                // 封装输⼊流,并指定字符集
                bufferedReader = new BufferedReader(new
                        InputStreamReader(inputStream, StandardCharsets.UTF_8));
                // 存放数据
                StringBuilder sbf = new StringBuilder();
                String temp;
                while ((temp = bufferedReader.readLine()) !=
                        null) {
                    sbf.append(temp);

                    sbf.append(System.getProperty("line.separator"));
                }
                result = sbf.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();// 关闭远程连接
            }
        }
        return result;
    }
    /**
     * post⽅式的http请求
     *
     * @param httpUrl 请求地址
     * @param param 请求参数
     * @return 返回结果
     */
    public static String doPost(String httpUrl, String param,String contentType) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;
        try {
            java.net.URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection)
                    url.openConnection();
            // 设置连接请求⽅式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60000毫秒
            connection.setReadTimeout(60000);
            // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
            connection.setDoOutput(true);
            // 设置传⼊参数的格式:请求参数应该是name1=value1&name2=value2 的形式。
            connection.setRequestProperty("Content-Type",contentType);
            // 通过连接对象获取⼀个输出流
            outputStream = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            outputStream.write(param.getBytes());
            // 通过连接对象获取⼀个输⼊流,向远程读取
            if (connection.getResponseCode() == 200) {
                inputStream = connection.getInputStream();
                // 对输⼊流对象进⾏包装:charset根据⼯作项⽬组的要求来设置
                bufferedReader = new BufferedReader(new
                        InputStreamReader(inputStream, StandardCharsets.UTF_8));
                StringBuilder sbf = new StringBuilder();
                String temp;
                // 循环遍历⼀⾏⼀⾏读取数据
                while ((temp = bufferedReader.readLine()) !=
                        null) {
                    sbf.append(temp);

                    sbf.append(System.getProperty("line.separator"));
                }
                result = sbf.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }


    //httpClient发送携带文件的post请求

    /**
     * 以post方式调用第三方接口,以form-data 形式  发送 文件
     * @param url post请求url
     * @param map
     * @param localFile 文件地址
     * @param fileParamName 文件参数名称
     * @return
     */
    public static String doPostByFile(String url, Map<String, String> map, String localFile, String fileParamName) {
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 把文件转换成流对象FileBody
            FileBody bin = new FileBody(new File(localFile));
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addPart(fileParamName, bin);
            if (map != null) {
                for (String key : map.keySet()) {
                    builder.addPart(key,
                            new StringBody(map.get(key), ContentType.create("text/plain", Consts.UTF_8)));
                }
            }
            HttpEntity reqEntity = builder.build();
            httpPost.setEntity(reqEntity);
            // 发起请求 并返回请求的响应
            response = httpClient.execute(httpPost, HttpClientContext.create());
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        }  catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null)
                    response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }
}

4.2 TokenUtil:获取 Access token的工具类

package com.zsh.wx_account1.util;

import com.zsh.wx_account1.entity.AccessToken;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.ObjectUtils;

/**
 * 获取 Access token的工具类
 * @Author ZhaoShuHao
 * @Date 2023/8/23 9:44
 */
public class TokenUtil {
    //自己的公众号信息
    //测试号
    private static final String APP_ID = "321312321321";
    private static final String APP_SECRET = "321321321321312332";
    //自己的公众号
   /* private static final String APP_ID = "321321321321";
    private static final String APP_SECRET = "3123123123123";*/
    private static AccessToken accessToken = new AccessToken();
    public static void main(String[] args) {

    //{"access_token":"63_8R2EcPuM3dz_D81Q2FBiSfgrlwokafQloAU33iFhHIbjabRFtC_thRqk7VOkMbarQ8lA9yyq2pgwh4pc6P-5qQutc6WWMLwFafIR6ZaLkB299OJU78npFt--I0ACXCiACAHCH","expires_in":7200}
        System.out.println(getAccessToken());
    }
    private static void getToken(){
        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
                APP_ID,
                APP_SECRET);
        String result = HttpUtil.doGet(url);
        if(StringUtils.isNotBlank(result)){
            JSONObject jsonObject = JSONObject.fromObject(result);
            String token = jsonObject.getString("access_token");
            long expiresIn = jsonObject.getLong("expires_in");
            accessToken.setToken(token);
            accessToken.setExpireTime(expiresIn);
        }
    }
    /**
     * 获取AccessToken
     * @return
     */
    public static String getAccessToken(){
        //如果accessToken为空或者超时,都重新获取token
        if(ObjectUtils.isEmpty(accessToken) || accessToken.isExpired()){
            getToken();
        }
        return accessToken.getToken();
    }
}

 4.3 AccessTokenUtil:微信授权登录

package com.zsh.wx_account1.util;

import com.alibaba.fastjson.JSON;
import org.junit.jupiter.api.Test;

import java.util.Map;

/**
 * 关于微信授权登录
 * @Author ZhaoShuHao
 * @Date 2023/9/1 13:48
 */
//微信授权登录,第二步,根据第一步授权后返回的code获取access_token(code可以从重定向的路径中获取)
public class AccessTokenUtil {
    private static final String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

    //自己的公众号信息
    //测试号
    private static final String APP_ID = "3123213421432423";
    private static final String APP_SECRET = "421412421344";
    //code一般只有5分钟的过期时间,过期后需要重新获取
    private static final String CODE="071Iy4ml2pjvXb4ujbll2Eg5644Iy4mb";
    public static void main(String[] args) {
        //1、根据code获取信息
      /*  Map accessToken = getAccessToken();
        System.out.println("accessToken:"+accessToken);*/
        //2、根据refreshToken刷新token
     /*   String s = refreshTokenTest();
        System.out.println(s);*/
        //3、拉去用户信息
//        String s = pullUserInfo();
        //微信授权获取用户信息的完整流程
        weChatAuthorization();
    }
    /*1、根据code获取的数据
    {
	"access_token": "72_hts4ZVuBZJKc2vROr84IZLudWXkBPrn_1pE44FgTWo_UYxu-AwzWdaI81RMulEDXrYwuOe2Src0FH4UVo_YoArFBvWW8rQEu_O5tDbUaJBs",
	"expires_in": 7200,
	  "refresh_token": "72_ESvv83WfSTTPr4MAUH4ecI-2RWRhASkWgKqyCeWWLBABWIhxWUr-_R7E1i5Yxs4CFwEf6Y44fUi0UyPinV0xdDnnXsJKe_2xYabiNyDd7W0",
	"openid": "okuVs5iLGbRWwjjotu8EsKVURyDM",
	"scope": "snsapi_userinfo"
    }
    * */
    public static Map<String,Object> getAccessToken(){
        String formatUrl = String.format(url, APP_ID, APP_SECRET, CODE);
        System.out.println("formatUrl:"+formatUrl);
        String s = HttpUtil.doGet(formatUrl);
        Map<String,Object> map = JSON.parseObject(s, Map.class);
        return map;
    }

    /*
    {
	"openid": "okuVs5iLGbRWwjjotu8EsKVURyDM",
	"access_token": "72_DmkvFgDsiySmI22VMVn82qlzlZ_tQfdu5sns-81ALUFXMK7StU9fRgxKRFQaQuW_QIgC2oGGF9jSAAowb3TVBW1jSPpCZSJgFAsmjXxQ6wc",
	"expires_in": 7200,
	"refresh_token": "72_VXoP27NOxJxILa1-MRT_2N-8Tt6mUwOrycLGjGt61j1UicZx3uwcVONRrpJdDXJvvUmSOfuiZ0iI5DD6HBB0LbgmUMEqJSMEsb7VXQXifNE",
	"scope": "snsapi_userinfo"
    }
    * */
    //2、(可选)因为accessToken的过期时间较短,可以使用refresh_token去刷新accessToken
    public static String refreshToken(String refreshToken){
        String format = String.format("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s", APP_ID, refreshToken);
        String s = HttpUtil.doGet(format);
        System.out.println("tokenInfo:"+s);
        return s;
    }
    //因为accessToken的过期时间较短,可以使用refresh_token去刷新accessToken
    public static String refreshTokenTest(){
        String format = String.format("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s", APP_ID, "72_VXoP27NOxJxILa1-MRT_2N-8Tt6mUwOrycLGjGt61j1UicZx3uwcVONRrpJdDXJvvUmSOfuiZ0iI5DD6HBB0LbgmUMEqJSMEsb7VXQXifNE");
        String s = HttpUtil.doGet(format);
        System.out.println("tokenInfo:"+s);
        return s;
    }

    /*
    {
	"openid": "okuVs5iLGbRWwjjotu8EsKVURyDM",
	"nickname": "要开心吖",
	"sex": 0,
	"language": "",
	"city": "",
	"province": "",
	"country": "",
	"headimgurl": "https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/DYAIOgq83erD0Q9Iv5YFf31GpZG36Mjmtcee8VyOxmnrlXn1hXH61P3DZmENrrpBalGP5WJ0Qe2KW6g7bPopiaQ\/132",
	"privilege": []
}
    * */
    //3、拉取用户信息
    public static String pullUserInfo(){
        String accessToken="72_DmkvFgDsiySmI22VMVn82qlzlZ_tQfdu5sns-81ALUFXMK7StU9fRgxKRFQaQuW_QIgC2oGGF9jSAAowb3TVBW1jSPpCZSJgFAsmjXxQ6wc";
        String openId="okuVs5iLGbRWwjjotu8EsKVURyDM";
        String format = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN", accessToken, openId);
        String s = HttpUtil.doGet(format);
        System.out.println(s);
        return s;
    }

    //微信授权的完整流程
    public static String weChatAuthorization(){
        String formatUrl = String.format(url, APP_ID, APP_SECRET, CODE);
        System.out.println("formatUrl:"+formatUrl);
        String tokeninfo = HttpUtil.doGet(formatUrl);
        Map<String,Object> map = JSON.parseObject(tokeninfo, Map.class);
        String accessToken= (String) map.get("access_token");
        String openId= (String) map.get("openid");
        String format = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN", accessToken, openId);
        String userInfo = HttpUtil.doGet(format);
        System.out.println("tokeninfo:"+tokeninfo);
        System.out.println("userInfo:"+userInfo);
        return userInfo;
    }


}

4.4 IdiomJielongUtil:聚合数据-成语接龙

package com.zsh.wx_account1.util;
import com.alibaba.fastjson.JSON;
import net.sf.json.JSONObject;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Random;

/**
 * 成语接龙
 * @Author ZhaoShuHao
 * @create 2023/08/25
 */
public class IdiomJielongUtil {
    public static void main(String[] args) {
        startIdiomJielong("一心一意");
    }

    public static String startIdiomJielong(String parm){
        // 发送http请求的url
        String url = "http://apis.juhe.cn/idiomJie/query";

        Map<String, String> params = new HashMap<String, String>();
        params.put("key", "e3e9e5aaa95d4fe394d16f3d46621362"); // 在个人中心->我的数据,接口名称上方查看
        params.put("wd", parm); // 查询的成语,如:一心一意
        String paramsStr = urlencode(params);
        System.out.println(paramsStr);
        String response = doGet(url,paramsStr);
        // // post请求
        // String response = doPost(url,paramsStr);

        // 输出请求结果
        System.out.println(response);

        try {
            Map map = JSON.parseObject(response, Map.class);
            Map<String,Object> result = (Map<String, Object>) map.get("result");
            List<String> data = (List<String>) result.get("data");
            String last_word = (String) result.get("last_word");
            int i = new Random().nextInt(data.size());

            // 解析请求结果,json:
            JSONObject jsonObject = JSONObject.fromObject(response);
            System.out.println(jsonObject);

            System.out.println("成句接龙:最后一个字为:"+last_word+",俺的回答是:"+data.get(i)+",请老大您回答");
            return "成句接龙:最后一个字为:"+last_word+",俺的回答是:"+data.get(i)+",请老大您继续作答:";
            // 具体返回示例值,参考返回参数说明、json返回示例
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "您太牛了,我认输!";
    }
    // 将map型转为请求参数型
    public static String urlencode(Map<String, String> data) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry i : data.entrySet()) {
            try {
                sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue() + "", "UTF-8")).append("&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    /**
     * get方式的http请求
     *
     * @param httpUrl 请求地址
     * @param paramStr 请求参数
     * @return 返回结果
     */

    public static String doGet(String httpUrl,String paramStr) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;// 返回结果字符串
        try {
            httpUrl += "?"+paramStr;
            // 创建远程url连接对象
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式:get
            connection.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);
            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 发送请求
            connection.connect();
            // 通过connection连接,获取输入流
            if (connection.getResponseCode() == 200) {
                inputStream = connection.getInputStream();
                // 封装输入流,并指定字符集
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                // 存放数据
                StringBuilder sbf = new StringBuilder();
                String temp;
                while ((temp = bufferedReader.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append(System.getProperty("line.separator"));
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();// 关闭远程连接
            }
        }
        return result;
    }

    /**
     * post方式的http请求
     *
     * @param httpUrl 请求地址
     * @param paramStr   请求参数
     * @return 返回结果
     */
    public static String doPost(String httpUrl, String paramStr) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;
        try {
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间:60000毫秒
            connection.setReadTimeout(60000);
            // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
            connection.setDoOutput(true);
            // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // 通过连接对象获取一个输出流
            outputStream = connection.getOutputStream();
            // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
            outputStream.write(paramStr.getBytes());
            // 通过连接对象获取一个输入流,向远程读取
            if (connection.getResponseCode() == 200) {
                inputStream = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                StringBuilder sbf = new StringBuilder();
                String temp;
                // 循环遍历一行一行读取数据
                while ((temp = bufferedReader.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append(System.getProperty("line.separator"));
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != outputStream) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }
}

 4.5 JokesUtil:聚合数据-笑话大全

package com.zsh.wx_account1.util;
import com.alibaba.fastjson.JSON;
import com.google.common.primitives.Ints;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;


/**
 * 笑话大全工具类
 * @Author ZhaoShuHao
 * @create 2023/08/25
 */
public class JokesUtil {
    //接口请求地址
    //按更新时间查询笑话
    public static final String URL_A = "http://v.juhe.cn/joke/content/list.php?key=%s&&time=%d&pagesize=%d";

    //最新笑话
    public static final String URL_B = "http://v.juhe.cn/joke/content/text.php?key=%s&pagesize=%d";

    //随机笑话
    public static final String URL_C = "http://v.juhe.cn/joke/randJoke.php?key=%s";

    //申请接口的请求key
    // TODO: 您需要改为自己的请求key
    public static final String KEY = "0b2273f36f7be68b3a78bd9c4d2279b4";


    public static void main(String[] args) {

        // TODO: 日期

        //时间戳
        long time = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        //每页数量
        int pageSize = 2;

       /* System.out.println("------------按更新时间查询笑话-----------------");
        printA(time, pageSize);
        System.out.println("------------最新笑话-----------------");
        printB(pageSize);*/
        System.out.println("------------随机笑话-----------------");
        String s = printC();
        System.out.println(s);
    }
    /**
     * 随机笑话
     *
     */
    public static String printC() {
        //发送http请求的url
        String url = String.format(URL_C, KEY);
        final String response = HttpUtil.doGet(url);
        StringBuilder contents = new StringBuilder();
        List<String> list = new ArrayList<>();
        System.out.println("接口返回:" + response);
        final int[] num = {0};
        try {
            JSONObject jsonObject = JSONObject.fromObject(response);
            int error_code = jsonObject.getInt("error_code");
            if (error_code == 0) {
                System.out.println("调用接口成功");
                JSONArray result = jsonObject.getJSONArray("result");
                result.stream().map(JSONObject::fromObject).forEach(hour -> {
                    list.add(((JSONObject) hour).getString("content"));
                    System.out.println("content:" + ((JSONObject) hour).getString("content"));
                    System.out.println("hashId:" + ((JSONObject) hour).getString("hashId"));
                    System.out.println("unixtime:" + ((JSONObject) hour).getString("unixtime"));
                });

            } else {
                System.out.println("调用接口失败:" + jsonObject.getString("reason"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        contents.append("1、"+ list.get(0)+"\r\n")
                .append("2、"+ list.get(3)+"\r\n")
                .append("3、"+ list.get(5)+"\r\n")
                .append("4、"+ list.get(7)+"\r\n")
                .append("5、"+ list.get(9)+"\r\n");;
        return String.valueOf(contents);
    }
    /**
     * 最新笑话
     *
     * @param pageSize int 每页数量
     */
    public static void printB( int pageSize) {
        //发送http请求的url
        String url = String.format(URL_B, KEY, pageSize);
        final String response = HttpUtil.doGet(url);
        System.out.println("接口返回:" + response);
        try {
            JSONObject jsonObject = JSONObject.fromObject(response);
            int error_code = jsonObject.getInt("error_code");
            if (error_code == 0) {
                System.out.println("调用接口成功");
                JSONArray result = jsonObject.getJSONObject("result").getJSONArray("data");
                result.stream().map(JSONObject::fromObject).forEach(hour -> {
                    System.out.println("content:" + ((JSONObject) hour).getString("content"));
                    System.out.println("hashId:" + ((JSONObject) hour).getString("hashId"));
                    System.out.println("unixtime:" + ((JSONObject) hour).getString("unixtime"));
                    System.out.println("updatetime:" + ((JSONObject) hour).getString("updatetime"));
                });

            } else {
                System.out.println("调用接口失败:" + jsonObject.getString("reason"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 按更新时间查询笑话
     *
     * @param time     long 时间戳
     * @param pageSize int 每页数量
     */
    public static void printA(long time, int pageSize) {
        //发送http请求的url
        String url = String.format(URL_A, KEY, time, pageSize);

        final String response = HttpUtil.doGet(url);
        System.out.println("接口返回:" + response);
        try {
            JSONObject jsonObject = JSONObject.fromObject(response);
            int error_code = jsonObject.getInt("error_code");
            if (error_code == 0) {
                System.out.println("调用接口成功");
                JSONArray result = jsonObject.getJSONObject("result").getJSONArray("data");
                result.stream().map(JSONObject::fromObject).forEach(hour -> {
                    System.out.println("content:" + ((JSONObject) hour).getString("content"));
                    System.out.println("hashId:" + ((JSONObject) hour).getString("hashId"));
                    System.out.println("unixtime:" + ((JSONObject) hour).getString("unixtime"));
                    System.out.println("updatetime:" + ((JSONObject) hour).getString("updatetime"));
                });

            } else {
                System.out.println("调用接口失败:" + jsonObject.getString("reason"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



}

 4.6 RddleUtil:聚合数据-谜语大全

package com.zsh.wx_account1.util;


import com.alibaba.fastjson.JSON;

import java.util.Map;

/**
 * 谜语大全
 * @Author ZhaoShuHao
 * @create 2023/08/26
 */
public class RddleUtil {
    //申请接口的请求key
    // TODO: 您需要改为自己的请求key
    public static final String KEY = "213213213123213123";

    //谜语大全
    public static final String URL_C = "http://apis.juhe.cn/fapigx/riddle/query?key=%s";

    public static void main(String[] args) {
        getRddle();
    }
    //获取谜语
    public static String getRddle(){
        String url =String.format(URL_C,KEY);
        String result =  "对不起大佬,谜语大全出了点问题,请联系管理员小弟";
        try {
            String rddle = HttpUtil.doGet(url);;
            Map map = JSON.parseObject(rddle, Map.class);
            Map result1 = (Map) map.get("result");
            String quest = (String) result1.get("quest");
            String answer = (String) result1.get("answer");
            result= "大佬请猜猜谜语:"+"\r\n\r\n\r\n"+quest+"\r\n\r\n\r\n"+"您猜到了吗?"+"\r\n\r\n\r\n\r\n\r\n"+"让小子为您揭晓谜底吧,它就是:"+"\r\n\r\n\r\n\r\n\r\n"+answer;
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }
}

 4.7 SoupUtil:聚合数据-心灵鸡汤

package com.zsh.wx_account1.util;


import com.alibaba.fastjson.JSON;

import java.util.Map;

/**
 * 心灵鸡汤
 * @Author ZhaoShuHao
 * @create 2023/08/26
 */
public class SoupUtil {
    //申请接口的请求key
    // TODO: 您需要改为自己的请求key
    public static final String KEY = "xxxxxxxxxxxxxxxxxxx";

    //谜语大全
    public static final String URL_C = "https://apis.juhe.cn/fapig/soup/query?key=%s";

    public static void main(String[] args) {
        getSoup();
    }
    //获取谜语
    public static String getSoup(){
        String url =String.format(URL_C,KEY);
        String result =  "对不起大佬,心灵鸡汤出了点问题,请联系管理员小弟";
        try {
            String soup = HttpUtil.doGet(url);;
            System.out.println(soup);
            Map map = JSON.parseObject(soup, Map.class);
            Map result1 = (Map) map.get("result");
            String quest = (String) result1.get("text");
            result= "Good Good Study,Day Day Up;"+"\r\n\r\n\r\n"+"大佬正能量哦:"+"\r\n\r\n\r\n"+quest+"\r\n\r\n\r\n"+"传播新思想,弘扬正能量,大佬要开心哦!";
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }
}

 4.8 WordUtil:聚合数据-同义词/反义词

package com.zsh.wx_account1.util;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * @Author ZhaoShuHao
 * @Date 2023/8/22 16:36
 */
public class WordUtil {
    //聚合数据网站的api接口(同义词/反义词查询)
    public static final String WORD_URL = "http://apis.juhe.cn/tyfy/query?key=%s";
    //申请接⼝的请求key
    // TODO: 您需要改为⾃⼰的请求key
    public static final String KEY = "xxxxxxxxxxxxxxxxx";
    public static String getWords(String word) {
        HttpUtil httpUtil = new HttpUtil();
        //发送http请求的url
        String url = String.format(WORD_URL, KEY);
        final String response =httpUtil.doPost(url,"word="+word,"application/x-www-form-urlencoded");
        System.out.println("接⼝返回:" + response);
        try {
            JSONObject jsonObject =
                    JSONObject.fromObject(response);
            int error_code = jsonObject.getInt("error_code");
            if (error_code == 0) {
                System.out.println("调⽤接⼝成功");
                JSONObject result =
                        jsonObject.getJSONObject("result");
                JSONArray words = result.getJSONArray("words");
                StringBuilder stringBuilder = new
                        StringBuilder();
                words.stream().forEach(w->stringBuilder.append(w+" "));
                System.out.println(stringBuilder);
                return "'"+word+"'的同义词有:"+stringBuilder.toString();
            } else {
                System.out.println("调⽤接⼝失败:" +
                        jsonObject.getString("reason"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "'"+word+"'的同义词暂没找到,请联系管理员扩展";
    }

}

5.接口测试

5.1 自定义菜单

package com.zsh.wx_account1.controller;

import com.zsh.wx_account1.entity.*;
import com.zsh.wx_account1.util.HttpUtil;
import com.zsh.wx_account1.util.TokenUtil;
import net.sf.json.JSONObject;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 *  二级菜单
 * @Author ZhaoShuHao
 * @Date 2023/8/23 9:37
 */
public class TestButton {

    public static void main(String[] args) {
        //测试号
        String APP_ID = "xxxxxxxxxxxxxx";
        String url1="https://blog.csdn.net/ZhShH0413?spm=1010.2135.3001.5343";
        String encode = URLEncoder.encode(url1);
        String url2="https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
        String formatUrl = String.format(url2, APP_ID, encode);
        System.out.println(formatUrl);
        //创建一级菜单
        Button button = new Button();
        List<AbstractButton> buttons = new ArrayList<>();
        //一级菜单中的第一个按钮
        ClickButton clickButton = new ClickButton("笑话大全","jokes");
        //一级菜单中的第二个按钮
        ClickButton clickButton2 = new ClickButton("谜语大全","rddle");
        //一级菜单中的第三个按钮(二级菜单)
        SubButton subButton = new SubButton("快快点我");
        List<AbstractButton> subButtons = new ArrayList<>();
        //二级菜单的第一个按钮
//        subButtons.add(new ViewButton("大佬给个关注吧","https://blog.csdn.net/ZhShH0413?spm=1010.2135.3001.5343"));
        subButtons.add(new ViewButton("大佬给个关注吧",formatUrl));
        //二级菜单的第二个按钮
        subButtons.add(new ClickButton("心灵鸡汤","soup"));
        //二级菜单的第二个按钮
        subButtons.add(new PhotoOrAlbumButton("上传图片(带有文字的图片有惊喜哦)"));
        subButton.setSub_button(subButtons);
        //把一级菜单中的三个按钮添加进集合
        buttons.add(clickButton);
        buttons.add(clickButton2);
        buttons.add(subButton);
        //把集合添加到一级菜单中
        button.setButton(buttons);
        //转换成json字符串
        JSONObject jsonObject = JSONObject.fromObject(button);
        System.out.println(jsonObject);
        String json = jsonObject.toString();
        String url = String.format("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s", TokenUtil.getAccessToken());
        //发送请求
        String result = HttpUtil.doPost(url, json,"application/json;charset=utf-8");
        System.out.println(result);

    }

}

5.2 素材管理

package com.zsh.wx_account1.controller;

import com.zsh.wx_account1.util.HttpUtil;
import com.zsh.wx_account1.util.TokenUtil;
import org.junit.jupiter.api.Test;

/**
 * 素材管理
 * @Author ZhaoShuHao
 * @Date 2023/8/25 11:40
 */
public class TestMaterialManagement {
    //上传临时素材
    @Test
    public void testImage(){
        //这里上传了一个图片
        String url = String.format("https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s",
                TokenUtil.getAccessToken(),
                "image");
        String result = HttpUtil.doPostByFile(url, null, "src/main/resources/static/image/image1.jpg", "");
        System.out.println(result);
//{"type":"image","media_id":"gw-BxwWm3mP6T2M_OBR1IzPwl6YcFFncr4fx3CrS-wtJOd78l7evdmUm5e3b2BZP","created_at":1692935476,"item":[]}
    }

    /*
    图片地址:https://api.weixin.qq.com/cgi-bin/media/get?access_token=token的值&media_id=图片id
    https://api.weixin.qq.com/cgi-bin/media/get?access_token=71_3PiSMSASfd1s9s5CFK30XX3CaG3IamKRjT25tmfShuk4i2I3y3Ze0ebR0SSES-hro5T7zO5YVEo0pWiaedG3Yv5y4qRcoETPNRbqJJKOYxpH5ac_rD3CPtfCuZQTGGdAIAYLL&media_id=gw-BxwWm3mP6T2M_OBR1IzPwl6YcFFncr4fx3CrS-wtJOd78l7evdmUm5e3b2BZP
     */

    //获得临时素材
    @Test
    public void testGetImage(){
        String mediaId = "gw-BxwWm3mP6T2M_OBR1IzPwl6YcFFncr4fx3CrS-wtJOd78l7evdmUm5e3b2BZP";
        String url = String.format("https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s",
                TokenUtil.getAccessToken(),
                mediaId);
        String result = HttpUtil.doGet(url);
        System.out.println(result);

    }
}

5.3 自定义模板消息

package com.zsh.wx_account1.controller;

import com.zsh.wx_account1.util.HttpUtil;
import com.zsh.wx_account1.util.TokenUtil;
import org.junit.jupiter.api.Test;

/**
 * 测试模板消息
 * @Author ZhaoShuHao
 * @Date 2023/8/25 9:28
 */
public class TestModelMessage {
    //测试设置所属行业(模版消息的前置条件)
    @Test
    public void testSetTrade(){
        String url = String.format("https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=%s", TokenUtil.getAccessToken());
        String data = "{\n" +
                "    \"industry_id1\":\"1\",\n" +
                "    \"industry_id2\":\"4\"\n" +
                "}";
        String s = HttpUtil.doPost(url, data, "application/x-www-form-urlencoded");
        System.out.println(s);
    }
    //测试查询所属行业
    @Test
    public void testGetTrade(){
        String url = String.format("https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token=%s",TokenUtil.getAccessToken());
        System.out.println(HttpUtil.doGet(url));
    }
    //获取模版列表
    @Test
    public void testGetModelMessage(){
        String url = String.format("https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=%s", TokenUtil.getAccessToken());
        String s = HttpUtil.doGet(url);
        System.out.println(s);
    }


    //测试发送模版消息
    @Test
    public void testModelmessage(){
        String url = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", TokenUtil.getAccessToken());
         /*  String data = "{\n" +
                "           \"touser\":\"okuVs5iLGbRWwjjotu8EsKVURyDM\",\n" +
                "           \"template_id\":\"EOlNyURgdR1rnZx3_x_k9iHb4j5CZ3dshCZxZbCsU1w\",\n" +
                "           \"url\":\"https://blog.csdn.net/ZhShH0413?spm=1010.2135.3001.5343\",\n" +
                "           \"data\":{\n" +
                "                   \"keyword1\": {\n" +
                "                       \"value\":\"张三,恭喜您报名比赛成功\"\n" +
                "                   },\n" +
                "                   \"keyword2\":{\n" +
                "                       \"value\":\"A队\"\n" +
                "                   },\n" +
                "                   \"keyword3\": {\n" +
                "                       \"value\":\"2023年8月26日 7:00\"\n" +
                "                   },\n" +
                "                   \"keyword4\": {\n" +
                "                       \"value\":\"XX集团东大门\"\n" +
                "                   },\n" +
                "                   \"keyword5\": {\n" +
                "                       \"value\":\"A队1人,B队66人\"\n" +
                "                   },\n" +
                "                   \"keyword6\":{\n" +
                "                       \"value\":\"点击链接有惊喜,双击关注666\"\n" +
                "                   }\n" +
                "           }\n" +
                "       }";*/
        String data = "{\n" +
                "\t\"data\":{\n" +
                "\t\t\"CONTENT\":{\n" +
                "\t\t\t\"color\":\"\",\n" +
                "\t\t\t\"value\":\"通知通知通知通知通知\"\n" +
                "\t\t}\n" +
                "\t},\n" +
                "\t\"template_id\":\"gDN9OJDU4aXG0I4jbwww-6RFjS3YLMs8cHG8bJSpdU0\",\n" +
                "\t\"touser\":\"okuVs5iLGbRWwjjotu8EsKVURyDM\"\n" +
                "}";
        System.out.println(HttpUtil.doPost(url, data,"application/x-www-form-urlencoded"));
    }



}

5.4 用户账号管理

package com.zsh.wx_account1.controller;

import com.zsh.wx_account1.util.HttpUtil;
import com.zsh.wx_account1.util.TokenUtil;
import org.junit.jupiter.api.Test;

import java.net.HttpCookie;

/**
 * 用户账号管理
 * @Author ZhaoShuHao
 * @Date 2023/8/25 13:25
 */
public class TestAccountManagement {
    //生成带参数的二维码
    @Test
    public void testQRcode(){
        String url = String.format(" https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s",
                TokenUtil.getAccessToken());
        String data = "{\"expire_seconds\": 604800, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": 123}}}";
        String s = HttpUtil.doPost(url, data, "application/x-www-form-urlencoded");
        System.out.println(s);
    }
    /*
    https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET
    * https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQEA8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyeW1TVFVPaUJkSUMxVFhTTk5BMVkAAgR7POhkAwSAOgkA
     * */
    //通过ticket换取二维码
    @Test
    public void testGetQRcode(){
        String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQEA8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyeW1TVFVPaUJkSUMxVFhTTk5BMVkAAgR7POhkAwSAOgkA";
        String s = HttpUtil.doGet(url);
        System.out.println(s);
    }
}

5.5 处理公众号的一些事件(关注、文字、图片、按钮)

package com.zsh.wx_account1.controller;

import com.baidu.aip.ocr.AipOcr;
import com.thoughtworks.xstream.XStream;
import com.zsh.wx_account1.entity.Article;
import com.zsh.wx_account1.entity.NewsMessage;
import com.zsh.wx_account1.entity.TextMessage;
import com.zsh.wx_account1.util.*;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.function.Consumer;

/**
 * @Author ZhaoShuHao
 * @Date 2023/8/21 16:11
 */
@RestController
@RequestMapping("/wxTest/wx")
public class GetWxController {
    //百度AI的个人相关信息
    public static final String APP_ID = "xxxxxxx";
    public static final String API_KEY = "xxxxxxxxxxxxxxxx";
    public static final String SECRET_KEY = "xxxxxxxxxxxxx";
    //定义click按钮的eventKey,方便区分
    //笑话大全
    public static final String JOKES = "jokes";
    //谜语大全
    public static final String RDDLE = "rddle";
    //心灵鸡汤
    public static final String SOUP = "soup";
    /*校验信息是否来自微信服务器
    signature:微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
    timestamp: 时间戳
    nonce:随机数
    echostr:随机字符串
    * */
    @GetMapping("/")
    public String checkToken(String signature,String timestamp,String nonce,String echostr){
        // 1)将token、timestamp、nonce三个参数进⾏字典序排序
        String token = "zsh";
        List<String> list = Arrays.asList(token, timestamp, nonce);
        //排序
        Collections.sort(list);
        System.out.println("signature:"+signature);
        System.out.println("list:"+list);
        // 2)将三个参数字符串拼接成⼀个字符串进⾏sha1加密
        StringBuilder stringBuilder = new StringBuilder();
        list.stream().forEach(s -> stringBuilder.append(s));
        System.out.println("stringBuilder.toString():"+stringBuilder.toString());
        //加密
        try {
            MessageDigest sha1 = MessageDigest.getInstance("sha1");
            //使用sha1进行加密,获得byte[]数组
            byte[] digest = sha1.digest(stringBuilder.toString().getBytes());
            System.out.println("digest:"+digest);
            System.out.println("digest.toString():"+  digest.toString());
            System.out.println("new String(digest):"+ new String(digest));
            System.out.println("Arrays.toString(digest):"+ Arrays.toString(digest));
//            String sum = integerToHexString(digest);
//            String sum = stringFormat(digest);
            String sum = integerToHexString2(digest);
            // 3)开发者获得加密后的字符串可与 signature 对⽐,标识该请求来源于微信
            if (!StringUtils.isEmpty(signature) && signature.equals(sum)) {
                System.out.println("sum:"+sum);
                return echostr;
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
    //第一种方式,课程上的方式(使用Integer.toHexString)
    private String integerToHexString(byte[] digest){
        StringBuilder sum = new StringBuilder();
        for (byte b : digest) {
            sum.append(Integer.toHexString((b>>4)&15));
            sum.append(Integer.toHexString(b&15));
        }
        return sum.toString();
    }
   /* 第二种方式(字符串格式 %02xString.format())
   * 这String.format是将字节数组转换为十六进制的最简单和明显的方法,%02x对于小写十六进制,%02X大写十六进制。
   * */
    private String stringFormat(byte[] digest){
        StringBuilder sum = new StringBuilder();
        for (byte b : digest) {
            sum.append(String.format("%02x", b));
        }
        return sum.toString();
    }
    //第三种方式(Integer.toHexString(decimal))
    private String integerToHexString2(byte[] digest){
        StringBuilder result = new StringBuilder();
        for (byte aByte : digest) {
            int decimal = (int) aByte & 0xff;               // bytes widen to int, need mask, prevent sign extension
            // get last 8 bits
            String hex = Integer.toHexString(decimal);
            if (hex.length() % 2 == 1) {                    // if half hex, pad with zero, e.g \t
                hex = "0" + hex;
            }
            result.append(hex);
        }
        return result.toString();
    }

    //获取用户向测试号发送的消息,输出到控制台上
    /*@PostMapping("/")
    public String receiveMessage(HttpServletRequest request) throws IOException{
        ServletInputStream inputStream = request.getInputStream();
        byte[] bytes = new byte[1024];
        System.out.println("inputStream:"+inputStream);
        int len = 0;
        while ((len=inputStream.read(bytes))!=-1){
            System.out.println(new String(bytes, 0, len));
        }
        return "";
    }*/
    //获取用户向测试号发送的消息,并解析,封装成map结构
    @PostMapping("/")
    public String receiveMessage(HttpServletRequest request) throws IOException{
        ServletInputStream inputStream = request.getInputStream();
        Map<String, String> map = new HashMap<>();
        //获取xml解析工具类
        SAXReader saxReader = new SAXReader();
        try {
            //读取request输⼊流,获得Document对象
            Document document = saxReader.read(inputStream);
            //获得root节点
            Element rootElement = document.getRootElement();
            //获取所有子节点
            List<Element> elements = rootElement.elements();
            elements.stream().forEach(new Consumer<Element>() {
                @Override
                public void accept(Element element) {
                    map.put(element.getName(),element.getStringValue());
                }
            });

        } catch (DocumentException e) {
            e.printStackTrace();
        }
        System.out.println("消息为:"+map);
        //回复消息的格式必须为xml的格式
        //1、简单的回复
        /*String message ="<xml> " +
                "<ToUserName><![CDATA[okuVs5iLGbRWwjjotu8EsKVURyDM]]></ToUserName>" +
                " <FromUserName><![CDATA[gh_54b74a688c3b]]></FromUserName>" +
                " <CreateTime>1692685746</CreateTime> <MsgType><![CDATA[text]]>" +
                "</MsgType> <Content><![CDATA[你好]]></Content> " +
                "</xml>";*/
        //2、封装消息回复
//        String message = getReplyMessageByWord(map);

        String message = null;
        String msgType = map.get("MsgType");
        switch (msgType){
            case "text":
                if(map.get("Content").equals("图文")){
                    //回复图文信息
                    message = getReplyNewsMessage(map);
                }else {
                    //成语接龙
                    String content = IdiomJielongUtil.startIdiomJielong(map.get("Content"));
                    message = assembleTextXMLFormat(content,map);
                    //3、消息处理案例-接⼊第三⽅服务接⼝(获取同义词)
                    //message = getReplyMessageByWord(map);
                }
                break;
            case "event":
                //处理事件
                message = handleEvent(map);
                break;
            case "image":
                message=handleImage(map);
                break;
            default:
                break;
        }
        System.out.println(message);
        return message;
    }
    //2、封装消息格式
   /* private String getReplyMessageByWord(Map<String, String> map) {
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setMsgType("text");
        textMessage.setContent("哈哈哈哈哈哈哈哈哈");
        textMessage.setCreateTime(System.currentTimeMillis()/1000);
        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }*/
    //封装文本text的xml结构(回复文本消息可以通用)
    private String assembleTextXMLFormat(String content,Map<String,String > map){
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setMsgType("text");
        textMessage.setContent(content);
        textMessage.setCreateTime(System.currentTimeMillis()/1000);
        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }
    //3.消息处理案例-接⼊第三⽅服务接⼝(获取同义词)
    private String getReplyMessageByWord(Map<String, String> map)
    {
        String content = WordUtil.getWords(map.get("Content"));
        return assembleTextXMLFormat(content,map);
    }
    //获取图文消息
    private String getReplyNewsMessage(Map<String, String> map) {
        NewsMessage newsMessage = new NewsMessage();
        newsMessage.setToUserName(map.get("FromUserName"));
        newsMessage.setFromUserName(map.get("ToUserName"));
        newsMessage.setMsgType("news");

        newsMessage.setCreateTime(System.currentTimeMillis()/1000);
        newsMessage.setArticleCount(1);
        List<Article> articles = new ArrayList<>();
        Article article = new Article();
        article.setTitle("要开心呀的csdn个人中心");
        article.setDescription("要开心呀的csdn个人中心,个人笔记、学习记录");
                article.setUrl("https://blog.csdn.net/ZhShH0413?spm=1000.2115.3001.5343");

        article.setPicUrl("http://mmbiz.qpic.cn/sz_mmbiz_jpg/IPwvTbhAHQL1rPJgNdCuD2udSmC7icF7bFtqdOejlAIFQo9HibTFLggqtbRfObia9XP90f9gSQ2mYWApBkSjcl1lA/0");
                articles.add(article);
        newsMessage.setArticles(articles);
        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(NewsMessage.class);
        String xml = xStream.toXML(newsMessage);
        return xml;
    }

    /**
     * 处理事件推送
     * @param map
     * @return
     */
    private String handleEvent(Map<String, String> map) {
        String message = null;
        String event = map.get("Event");
        switch (event){
            case "CLICK":
                String eventKey = map.get("EventKey");
                if(JOKES.equals(eventKey)){
                    String s = JokesUtil.printC();
                    message =assembleTextXMLFormat(s,map);
                }else if(RDDLE.equals(eventKey)){
                    String rddle = RddleUtil.getRddle();
                    message =assembleTextXMLFormat(rddle,map);
                }else if(SOUP.equals(eventKey)){
                    String soup = SoupUtil.getSoup();
                    message =assembleTextXMLFormat(soup,map);
                }
                break;
            case "VIEW":
                message =  assembleTextXMLFormat("view",map);
                System.out.println("view");
                break;
            case "pic_photo_or_album":
                message =  assembleTextXMLFormat("pic_photo_or_album",map);
                System.out.println("pic_photo_or_album");
            case "unsubscribe":
            case "subscribe":
                message = handleSubscribe(map);
                System.out.println("subscribe");
                break;
            default:
                break;
        }
        return message;
    }

    //借用百度Api实现网络图片文字识别
    private String handleImage(Map<String, String> map) {
        // 初始化⼀个AipOcr
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        // ⽹络图⽚⽂字识别, 图⽚参数为远程url图⽚
        String url = map.get("PicUrl");
        JSONObject res = client.webImageUrl(url, new HashMap<String,String>());
        System.out.println(res.toString(2));
        JSONArray wordsResult = res.getJSONArray("words_result");
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("大佬瞅我眼不眼熟:\r\n\r\n\r\n\r\n");
        Iterator<Object> iterator = wordsResult.iterator();
        while(iterator.hasNext()){
            JSONObject next = (JSONObject) iterator.next();
            stringBuilder.append(next.getString("words"));
        }
        stringBuilder.append("\r\n\r\n\r\n\r\n"+"没错,小弟我啊,还能文字识图,给个关注吧!");
        return  assembleTextXMLFormat(stringBuilder.toString(),map);
    }

    //关注事件
    private String handleSubscribe(Map<String,String > map){
        String content= "尊敬的大佬,欢迎您关注本公众号,小弟可以为您服务的有:\r\n(1)成语接龙:您只要输入一个成语,小弟就能做出回答,快来和小弟比划比划!" +
                "\r\n(2)图片文字识别:您发送一个带文字的图片,小弟就可以帮您识别文字!\r\n(3)笑话大全:可能不好笑,但小弟还是希望大佬能哈哈哈哈!" +
                "\r\n(4)谜语大全:快点来猜猜看吧,不能偷看答案哦!\r\n(5)心灵鸡汤:让小弟用鸡汤来安抚您吧,当然鸡汤可能不咋地!" +
                "\r\n大佬注意了:给小弟一个关注好不好,csdn求个关注,谢谢大佬!";
        return assembleSubscribeEnventXMLFormat(content,map);
    }

    //封装文本text的xml结构(回复文本消息可以通用)
    private String assembleSubscribeEnventXMLFormat(String content,Map<String,String > map){
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setMsgType("text");
        textMessage.setContent(content);
        textMessage.setCreateTime(System.currentTimeMillis()/1000);
        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }
}
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值