1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 微信公众号后台java开发实现自动回复机器人

微信公众号后台java开发实现自动回复机器人

时间:2020-10-23 09:53:35

相关推荐

微信公众号后台java开发实现自动回复机器人

1.注册微信公众号。(简单)

2.注册图灵机器人。(自己百度)

1)注册后可以拿到key (注意 api接入里的钥匙不要打开,否则要加解密,麻烦)

3.配置微信公众号服务器验证。

1)在开发的基本配置下,填写控制器servlet访问的路径。

2)token随意写,不过要和后台一致

3)选择明文

4)随机选个字符串

然后点击提交(这里微信会发送请求和你写的验证看是否匹配,具体看微信公众号平台开发文档) ?其实这里不用操作什么,他发送的匹配直接返回验证就过了,但是不是很安全。

4.接着是解析微信发送过来的xml格式,把他弄成map集合

5.解析得到内容 发送httpGet请求 丢过去给图灵机器人接口,返回回复内容

6.将东西封装成xml返回回去

然后OK

涉及的包 一个都不能少(当初就是少了commons-logging)

代码如下:

package com.lin.po;/** 文本消息<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId></xml>* *//*** 参数描述*ToUserName开发者微信号*FromUserName发送方帐号(一个OpenID)* CreateTime消息创建时间 (整型)*MsgTypetext*Content文本消息内容*MsgId消息id,64位整型* @author linxinda**/public class TextMessage {private String ToUserName;private String FromUserName;private long CreateTime;private String MsgType;private String Content;private String MsgId;public String getToUserName() {return ToUserName;}public void setToUserName(String toUserName) {ToUserName = toUserName;}public String getFromUserName() {return FromUserName;}public void setFromUserName(String fromUserName) {FromUserName = fromUserName;}public long getCreateTime() {return CreateTime;}public void setCreateTime(long createTime) {CreateTime = createTime;}public String getMsgType() {return MsgType;}public void setMsgType(String msgType) {MsgType = msgType;}public String getContent() {return Content;}public void setContent(String content) {Content = content;}public String getMsgId() {return MsgId;}public void setMsgId(String msgId) {MsgId = msgId;}}

package com.lin.servlet;import java.io.IOException;import java.io.PrintWriter;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.lin.po.TextMessage;import com.lin.util.MessageUtil;import com.lin.util.TulingApiUtil;import com.lin.util.WeChatConnectValidateUtil;public class WeChatServlet extends HttpServlet {public void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");PrintWriter out =resp.getWriter();try {Map<String, String> map=MessageUtil.xmlToMap(req);String toUserName=map.get("ToUserName");String fromUserName=map.get("FromUserName");String msgType=map.get("MsgType");String content=map.get("Content");String message=null;if("text".equals(msgType)){//System.out.println("text.equals(msgType)");TextMessage text =new TextMessage();text.setFromUserName(toUserName);text.setToUserName(fromUserName);text.setMsgType("text");//这里填写回复内容text.setContent(TulingApiUtil.getTulingResult(content));text.setCreateTime(new Date().getTime());message=MessageUtil.textMessageToXml(text);}//System.out.println(message);out.print(message);} catch (Exception e) {//System.out.println("doPost->try..catch");e.printStackTrace();}finally{out.close();}}/** Get方法是微信接入请求验证时用的 其他都是post请求* 参数描述signature微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。timestamp时间戳nonce随机数echostr随机字符串*///其实这里不用搞加密,直接返回echostr也行 只是不太安全protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {String signature=req.getParameter("signature");String timestamp=req.getParameter("timestamp");String nonce=req.getParameter("nonce");String echostr=req.getParameter("echostr");PrintWriter out =resp.getWriter();if(WeChatConnectValidateUtil.checkSignature(signature,timestamp,nonce)){out.print(echostr);}}}

package com.lin.util;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/*** 使用Java自带的MessageDigest类* @author linxinda*/public class EncryptionUtil {public static String getSha1(String source){// 用来将字节转换成 16 进制表示的字符// System.out.println("进getSha1");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(source.getBytes("UTF-8")); // 通过使用 update 方法处理数据,使指定的 byte数组更新摘要byte[] encryptStr = mdTemp.digest(); // 获得密文完成哈希计算,产生128 位的长整数int j=encryptStr.length;char buf[] = new char[j * 2]; int k = 0; // 表示转换结果中对应的字符位置for (int i = 0; i < j; i++) { // 从第一个字节开始,对每一个字节,转换成 j 进制字符的转换byte byte0 = encryptStr[i]; // 取第 i 个字节buf[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字节中高 4 位的数字转换, >>> 为逻辑右移,将符号位一起右移buf[k++] = hexDigits[byte0 & 0xf]; // 取字节中低 4 位的数字转换}// System.out.println(buf.toString());return new String(buf); // 换后的结果转换为字符串} catch (Exception e) {//System.out.println("getSha1->try...catch");e.printStackTrace();}return null;}}

package com.lin.util;import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.lin.po.TextMessage;import com.thoughtworks.xstream.XStream;import com.thoughtworks.xstream.io.xml.StaxDriver;public class MessageUtil {/*** xml转为map集合* @param request* @return* @throws IOException* @throws DocumentException*/public static Map<String,String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException{//System.out.println("进xmlToMap");Map<String,String> map=new HashMap<String, String>();//dom4j saxReader解析xmlSAXReader reader=new SAXReader();//从request中获取输入流InputStream ins = request.getInputStream();//解析xml文档Document doc =reader.read(ins);//获得根节点Element root = doc.getRootElement();//List存储 遍历List<Element> list= root.elements();for (Element e : list) {map.put(e.getName(), e.getText());}ins.close();// System.out.println(map.toString());return map; }/*** 将文本消息对象转换为xml* @param textMessage* @return*///xtream jar包 -> XStrem类提供对象转xmlpublic static String textMessageToXml(TextMessage textMessage){// System.out.println("进textMessageToXml");/*** new StaxDriver()这个很重要 没有这个就错了* XStream xstream=new XStream(new StaxDriver());*/XStream xstream=new XStream(new StaxDriver());xstream.alias("xml", textMessage.getClass());// System.out.println("textMessage");return xstream.toXML(textMessage); }}

package com.lin.util;import java.util.Arrays;public class WeChatConnectValidateUtil {//Token 和微信后台接入接口的token一致private final static String TOKEN="linxinda"; public static boolean checkSignature(String signature,String timestamp,String nonce){//System.out.println("进checkSignature");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]); }//sha1加密String temp=EncryptionUtil.getSha1(content.toString());// System.out.println(temp+" "+signature.equals(temp));return signature.equals(temp);}}

// 调用图灵机器人api接口,获取智能回复内容:package com.lin.util;import java.io.IOException;import java.io.UnsupportedEncodingException;import .URLEncoder;import org.apache.http.HttpResponse;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import org.json.JSONException;import org.json.JSONObject;/*** 调用图灵机器人api接口,获取智能回复内容* @author pamchen-1**/public class TulingApiUtil {/*** 调用图灵机器人api接口,获取智能回复内容,解析获取自己所需结果* @param content* @return*/private static final String KEY="这里填自己的key";public static String getTulingResult(String content){//System.out.println("传入的内容->"+content);/** 此处为图灵api接口,参数key需要自己去注册申请,先以11111111代替 */String apiUrl = "/openapi/api?key="+KEY+"&info=";String param = "";//System.out.println("!!!!!!!");try {param = apiUrl+URLEncoder.encode(content,"utf-8");} catch (UnsupportedEncodingException e1) {System.out.println("UnsupportedEncodingException");e1.printStackTrace();} //将参数转为url编码//System.out.println("?????????");/** 发送httpget请求 */HttpGet request = new HttpGet(param);String result = "";try {HttpResponse response = HttpClients.createDefault().execute(request);/*** 特别注意 这一步一定要加commons-logging 这个jar包 否则会没反应,调试了好久!!* 似乎这个jar包是打印信息的 */int code =response.getStatusLine().getStatusCode();if(code==200){result = EntityUtils.toString(response.getEntity());}else {//System.out.println("code="+code);}} catch (ClientProtocolException e) {System.out.println("ClientProtocolException");e.printStackTrace();} catch (IOException e) {System.out.println("IOException");e.printStackTrace();}/** 请求失败处理 */if(null==result){//System.out.println("null==result");return "对不起,你说的话真是太高深了……";}////System.out.println("...........");try {StringBuffer bf=new StringBuffer();String s="";JSONObject json = new JSONObject(result);//以code=100000为例,参考图灵机器人api文档/*** code 说明100000文本类200000链接类302000新闻类308000菜谱类*/if(100000==json.getInt("code")){s = json.getString("text");bf.append(s);}else if(200000==json.getInt("code")){s = json.getString("text");bf.append(s);bf.append("\n");s = json.getString("url");bf.append(s);}else if(302000==json.getInt("code")){//s = json.getString("text");s="待开发有点麻烦!\n";bf.append(s);}else if(308000==json.getInt("code")){//s = json.getString("text");s="待开发有点麻烦!\n";bf.append(s);}result=bf.toString();} catch (JSONException e) {System.out.println("JSONException");e.printStackTrace();}//System.out.println("机器人回复->"+result);return result;}}

package com.lin.test;import java.io.BufferedInputStream;import java.util.Scanner;import com.lin.util.TulingApiUtil;public class Test {public static void main(String[] args) {Scanner scanner=new Scanner(new BufferedInputStream(System.in));while(scanner.hasNext()){String content=scanner.next();System.out.println(TulingApiUtil.getTulingResult(content));}scanner.close();}}

最后总结自己遇到的问题,便于日后查看:

1. 图灵机器人的加密钥匙要关闭,否则就得进行加解密操作,他的api里有详细说明。

2.可以多写些测试类方便调试,不要每次都传到服务器上调试,好麻烦。

最后记下自己服务器的一些信息

service tomcat6/httpd/iptable restart

微信要80端口,一些忘记的命令见阿里云配置

转载请注明本文地址:微信公众号后台java开发实现自动回复机器人

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。