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

    xiaoxiao2021-12-13  50

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

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

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

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

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

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

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

    3)选择明文

    4)随机选个字符串

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

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

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

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

    然后OK

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

    代码如下:

    [java] view plain copy 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;  }            }  

    [java] view plain copy 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);              }      }  }   [java] view plain copy 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;    }  }   [java] view plain copy 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);             }  }   [java] view plain copy 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);  }  }   [java] view plain copy // 调用图灵机器人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;      }  }  

    [java] view plain copy 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端口,一些忘记的命令见阿里云配置

        上一篇Web Service调用下一篇linux下shell显示-bash-4.1#不显示路径解决方法
    转载请注明原文地址: https://ju.6miu.com/read-950057.html

    最新回复(0)