博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
微信公众号后台java开发实现自动回复机器人
阅读量:4137 次
发布时间:2019-05-25

本文共 10801 字,大约阅读时间需要 36 分钟。

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;/* * 文本消息
1348831860
1234567890123456
* *//** * 参数 描述 * ToUserName 开发者微信号 * FromUserName 发送方帐号(一个OpenID) * CreateTime 消息创建时间 (整型) * MsgType text * 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
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
xmlToMap(HttpServletRequest request) throws IOException, DocumentException{ //System.out.println("进xmlToMap"); Map
map=new HashMap
(); //dom4j saxReader解析xml SAXReader reader=new SAXReader(); //从request中获取输入流 InputStream ins = request.getInputStream(); //解析xml文档 Document doc =reader.read(ins); //获得根节点 Element root = doc.getRootElement(); //List存储 遍历 List
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类提供对象转xml public 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
// 调用图灵机器人api接口,获取智能回复内容:package com.lin.util;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.net.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 = "http://www.tuling123.com/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端口,一些忘记的命令见阿里云配置

转载地址:http://wcmvi.baihongyu.com/

你可能感兴趣的文章
JSP中的转义字符
查看>>
SQLException: The user specified as a definer ('root'@'%') does not exist
查看>>
Linux 操作指令收集
查看>>
CentOS 7下卸载MySQL方式(转)
查看>>
CentOS7 安装MySQL 5.6.43
查看>>
使用Java 导入/导出 Excel ----Jakarta POI
查看>>
本地tomcat 服务器内存不足
查看>>
IntelliJ IDAE 2018.2 汉化
查看>>
基于S5PV210的uboot移植中遇到的若干问题记录(一)DM9000网卡移植
查看>>
Openwrt源码下载与编译
查看>>
我和ip_conntrack不得不说的一些事
查看>>
Linux 查看端口使用情况
查看>>
文件隐藏
查看>>
两个linux内核rootkit--之二:adore-ng
查看>>
两个linux内核rootkit--之一:enyelkm
查看>>
关于linux栈的一个深层次的问题
查看>>
rootkit related
查看>>
mysql-应用案例-视图的应用
查看>>
什么是虚拟机?
查看>>
Microsoft Visual C++ 和 Borland C++ Builder 之比较
查看>>