前言:
1.运行效果图
1.1 关注事件
![](https://img-blog.csdnimg.cn/direct/576bab802f3247588969a84afd44bff7.png)
![](https://img-blog.csdnimg.cn/direct/9ed0e9a8c4a04510a3984fba311f0e2b.png)
1.2 笑话大全
![](https://img-blog.csdnimg.cn/direct/9b3890a0c0544f84943b82c02192a132.png)
1.3 谜语大全
![](https://img-blog.csdnimg.cn/direct/a7ff0b3181e84358b368692e7148c10d.png)
1.3 多级菜单
![](https://img-blog.csdnimg.cn/direct/fbc7b2e1d62042bf909c4f35ffba73d6.png)
1.4 按钮跳转事件
![](https://img-blog.csdnimg.cn/direct/3bae1ad4dfc547bd8cc33fe8a4d0d8b5.png)
![](https://img-blog.csdnimg.cn/direct/d381c47eb15542c49d9c1beb893036d5.png)
1.5 心灵鸡汤
![](https://img-blog.csdnimg.cn/direct/b4d2014f0caf408d972b4414e30fbd94.png)
1.6 图片文字识别
![](https://img-blog.csdnimg.cn/direct/5543a8be6c394e8eaf21951801634383.png)
![](https://img-blog.csdnimg.cn/direct/6966927e563448628f3e44e6115b9887.png)
1.7成语接龙(有点智障)
![](https://img-blog.csdnimg.cn/direct/0af644f622974981b0916b39ae1ae587.png)
2.项目结构
![](https://img-blog.csdnimg.cn/direct/8e3909bc2a694e689f9e5487f98eb80a.png)
3.xml依赖
![](https://img-blog.csdnimg.cn/direct/daac6a770df44ce485114010681dcec8.png)
<?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.工具类
![](https://img-blog.csdnimg.cn/direct/6bb06d06ad8b4de9884b2e39f46fb8a8.png)
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;
}
}