前文:由于微信现在不给钱,不给认证,所以只能搞个订阅号玩玩
如果想要自己的微信服务在外网也能访问,必须做个穿透,本文采用ngrok
1.首先装ngrok
用github账号登录,注册会经常失败
这种方式每次ngrok停掉,重启又变成新的ip,需要在微信的gua种管理页面更改,真正生产不建议用这个,有空可以研究花生壳
也有笔者说ngrok借助与tunnel可以实现稳定的地址映射,重启不影响,我验证了一下,这个服务现在用不了。
2.登录https://mp.weixin.qq.com创建自己的账号,每一个微信只能创建一种类型的公众号
搭建springboot应用程序
创建servlet
步骤:在运行类中添加
@ServletComponentScan
然后
@WebServlet(name = "WeixinServlet")//,urlPatterns = "/*"
public class WeixinServlet extends HttpServlet {
在get中进行认证
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("加载WeixinServlet成功");
String signature=request.getParameter("signature");
String timestamp= request.getParameter("timestamp");
String nonce= request.getParameter("nonce");
String echostr= request.getParameter("echostr");
PrintWriter out=response.getWriter();
if(CheckUtil.checkSignature(signature,timestamp,nonce)){
out.print(echostr);
}
}
注意token和管理页面配管理页面才能配置通过
public class CheckUtil {
private static final String token="imooc";
public static boolean checkSignature(String signature,String timestamp,String nonce){
String [] arr=new String []{token,timestamp,nonce};
//将排序
Arrays.sort(arr);
//生成字符串
StringBuffer content=new StringBuffer();
for (int i=0;i<arr.length;i++){
content.append(arr[i]);
}
//shar1加密
String temp=getSha1(content.toString());
return temp.equals(signature);
}
public static String getSha1(String str){
if(str == null || str.length()==0){
return null;
}
char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j*2];
int k = 0;
for(int i=0;i<j;i++){
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
这个token与这个管理页面紧密连接
严格匹配要不然验证不通过
然后根据开发者文档进行开发,在servlet的post里面进行处理
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.12</version>
</dependency>
<dependency>
<groupId>top.jfunc.common</groupId>
<artifactId>converter</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.2.3</version>
<classifier>jdk15</classifier><!-- jdk版本 -->
</dependency>
例如文本:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter printWriter = response.getWriter();
String message= MessageResponseUtil.getResponse(request,response);
System.out.println("你发送的消息是:"+message);
printWriter.print(message);
printWriter.close();
}
//https://blog.csdn.net/qq_33540481/article/details/87448218
public static String getResponse(HttpServletRequest request, HttpServletResponse response) throws IOException {
String message = null;
try {
Map<String, String> map = MessageUtil.xmlToMap(request);
String fromUserName = map.get("FromUserName");
String toUserName = map.get("ToUserName");
String msgType = map.get("MsgType");
switch (msgType){
//文本
case MessageUtil.MESSAGE_TEXT:
String content = map.get("Content");
if ("1".equals(content)) {
message = MessageUtil.initText(fromUserName, toUserName, MessageUtil.firstMenu());
} else if ("2".equals(content)) {
message = MessageUtil.initText(fromUserName, toUserName, MessageUtil.secondMenu());
} else if ("?".equals(content) || " ?".equals(content)) {
message = MessageUtil.initText(fromUserName, toUserName, MessageUtil.menuText());
} else {
message = MessageUtil.initText(fromUserName, toUserName, content);
}
break;
//图像
case MessageUtil.MESSAGE_IMAGE:
message =MessageUtil.initImage(map);
break;
//语音
case MessageUtil.MESSAGE_VOICE:
break;
//视频
case MessageUtil.MESSAGE_VIDEO:
break;
//位置
case MessageUtil.MESSAGE_LOCATION:
break;
//链接
case MessageUtil.MESSAGE_LINK:
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
return message;
}
public static String initText(String fromUserName, String toUserName, String content) {
TextMessage text=new TextMessage();
text.setFromUserName(toUserName);
text.setToUserName(fromUserName);
text.setMsgType("text");
text.setCreateTime(String.valueOf(new Date().getTime()/1000));
text.setContent("您发送的消息是:"+content);
String message=MessageUtil.textMessageToXml(text);
return message;
}
//将对象类型转化成xml类型
public static String textMessageToXml(BaseMessage baseMessage){
XStream xstream=new XStream();
xstream.processAnnotations(BaseMessage.class);
xstream.processAnnotations(TextMessage.class);
return xstream.toXML(baseMessage);
@XStreamAlias("xml")
public class TextMessage extends BaseMessage{
//文本消息内容
@XStreamAlias("Content")
private String content;
//消息id,64位整型
@XStreamAlias("MsgId")
private String msgId;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
}
@XStreamAlias("xml")
public class BaseMessage {
@XStreamAlias("ToUserName")
private String toUserName;
@XStreamAlias("FromUserName")
private String fromUserName;
@XStreamAlias("CreateTime")
private String createTime;
@XStreamAlias("MsgType")
private String msgType;
public String getToUserName() {
return toUserName;
}
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public String getFromUserName() {
return fromUserName;
}
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
}
例如:发送图像
<!-- https://mvnrepository.com/artifact/com.baidu.aip/java-sdk -->
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.12.0</version>
</dependency>
以图像识别为基础利用百度ai技术
//设置APPID/AK/SK
public static final String APP_ID = "21179084";
public static final String API_KEY = "5AqagjlMbXbiGnVGBvs328su";
public static final String SECRET_KEY = "53PCrU1NZlijuXDs3rxt3DLEm7hRwbyv";
public static String initImage(Map<String, String> map) {
String fromUserName = map.get("FromUserName");
String toUserName = map.get("ToUserName");
String msgType = map.get("MsgType");
String picUrl = map.get("PicUrl");
String msgId = map.get("MsgId");
String mediaId = map.get("MediaId");
// 初始化一个AipOcr
AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
// 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
// 可选:设置代理服务器地址, http和socket二选一,或者均不设置
// client.setHttpProxy("proxy_host", proxy_port); // 设置http代理
// client.setSocketProxy("proxy_host", proxy_port); // 设置socket代理
// 可选:设置log4j日志输出格式,若不设置,则使用默认配置
// 也可以直接通过jvm启动参数设置此环境变量
// System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");
HashMap<String, String> options = new HashMap<String, String>();
options.put("recognize_granularity", "big");
options.put("language_type", "CHN_ENG");
options.put("detect_direction", "true");
options.put("detect_language", "true");
options.put("vertexes_location", "true");
options.put("probability", "true");
// 调用接口
// String path = "C:/Users/peiyajie/Desktop/1.jpg";
// org.json.JSONObject res = client.basicGeneral(path, new HashMap<String, String>());
org.json.JSONObject res = client.generalUrl(picUrl, options);;
//对Json进行解析
JSONObject jsonObject= JSONObject.fromObject(res.toString());
JSONArray jsonArray= jsonObject.getJSONArray("words_result");
StringBuilder sb=new StringBuilder();
Iterator iterator= jsonArray.iterator();
while(iterator.hasNext()){
JSONObject temp= (JSONObject) iterator.next();
sb.append(temp.get("words"));
}
System.out.println(res.toString(2));
/* ImageMessage text=new ImageMessage();
text.setFromUserName(toUserName);
text.setToUserName(fromUserName);
text.setMsgType("image");
text.setCreateTime(String.valueOf(new Date().getTime()/1000));
text.setPicUrl(picUrl);
text.setMsgId(msgId);
text.setMediaId(mediaId);*/
TextMessage text=new TextMessage();
text.setFromUserName(toUserName);
text.setToUserName(fromUserName);
text.setMsgType("text");
text.setCreateTime(String.valueOf(new Date().getTime()/1000));
text.setContent("您发送的消息是:"+sb.toString());
String message=MessageUtil.textMessageToXml(text);
return message;
}
前提是要在百度上面
需要创建自己的应用,里面有相关使用说明
注册ngrock
1.点击ngrock.exe
2.ngrok authtoken your authtoken
3.ngrok http 8080