微信公众号后台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		消息创建时间 (整型)
 *	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<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解析xml
    	  SAXReader 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类提供对象转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<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 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端口,一些忘记的命令见阿里云配置


  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
微信公众号开发源码Java是用Java语言编写的用于开发微信公众号的源代码。微信公众号开发是指通过开发者账号申请成为微信公众号开发者,利用微信提供的开发接口和SDK来开发和管理公众号。 Java作为一种广泛应用于企业级开发的编程语言,在微信公众号开发中也得到了广泛应用。通过使用Java开发微信公众号,可以实现公众号的业务逻辑,包括用户管理、消息推送、菜单设置、素材管理等功能,以及与其他系统的对接、数据的处理和存储等。 对于开发微信公众号的源码来说,Java源码通常包括了处理微信服务器与开发者服务器之间的消息通信和交互的代码,以及各类功能模块的实现代码。开发者可以根据自己的需求和业务逻辑,使用Java语言编写各种业务逻辑代码,并通过开发工具集成微信提供的SDK库来实现与微信服务器之间的交互。 在Java源码的基础上,开发者还可以根据需要进行定制和扩展,以满足更具体的业务需求。可以添加自定义的功能模块或者对现有功能进行修改和优化,以适应不同的应用场景和业务要求。 总之,微信公众号开发源码Java是用于开发微信公众号的源代码,通过使用Java语言和相应的开发工具,开发者可以自定义和实现具体的业务功能,满足不同用户的需求,并与微信服务器进行消息交互,为用户提供更好的微信公众号服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值