首页 > 编程 > Java > 正文

基于springboot微信公众号开发(微信自动回复)

2019-11-26 08:22:34
字体:
来源:转载
供稿:网友

效果图

1.准备工作

申请微信订阅号(个人只能申请订阅号,而且没什么功能,也无法认证),申请完毕,点击 开发=>基本配置,如下图:

服务器配置需要有 域名 80端口,我猜你没有,这里推荐个实用工具,pagekite,下载链接,

这个工具需要 python2.7以上环境,还有邮箱一个,一个邮箱一个月,邮箱这东西大家懂得,

用pagekite申请完域名,就可以用自己的电脑做订阅号服务器了.

2.服务器代码

创建个springboot工程

pom.xml

<properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>1.8</java.version>  </properties>  <parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>1.5.9.RELEASE</version>  </parent>  <dependencies>    <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-web</artifactId>    </dependency>        <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-thymeleaf</artifactId>    </dependency>    <!-- 使thymeleaf支持h5标签 -->    <dependency>      <groupId>net.sourceforge.nekohtml</groupId>      <artifactId>nekohtml</artifactId>      <version>1.9.22</version>    </dependency>    <dependency>			      <groupId>dom4j</groupId>			      <artifactId>dom4j</artifactId>			      <version>1.6.1</version>		    </dependency>  </dependencies>  <build>    <plugins>      <plugin>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-maven-plugin</artifactId>      </plugin>    </plugins>  </build>

入口类

@SpringBootApplicationpublic class WeChatApplication {  public static void main(String[] args) {    SpringApplication.run(WeChatApplication.class, args);    System.out.println("====启动成功====");  }}

application.properties,配置server.port=80

Controller,这个是处理微信请求,get方法就是微信公众平台 服务器配置url请求的路径,post是处理用户事件

@RestControllerpublic class WeChatController {  @Autowired  private WeChatService weChatService;  /**   * 处理微信服务器发来的get请求,进行签名的验证   *    * signature 微信端发来的签名   * timestamp 微信端发来的时间戳   * nonce   微信端发来的随机字符串   * echostr  微信端发来的验证字符串   */  @GetMapping(value = "wechat")  public String validate(@RequestParam(value = "signature") String signature,      @RequestParam(value = "timestamp") String timestamp,       @RequestParam(value = "nonce") String nonce,      @RequestParam(value = "echostr") String echostr) {    return WeChatUtil.checkSignature(signature, timestamp, nonce) ? echostr : null;  }  /**   * 此处是处理微信服务器的消息转发的   */  @PostMapping(value = "wechat")  public String processMsg(HttpServletRequest request) {    // 调用核心服务类接收处理请求    return weChatService.processRequest(request);      }}

Service,处理post请求

/** * 核心服务类 */@Servicepublic class WeChatServiceImpl implements WeChatService{  @Autowired  private FeignUtil feignUtil;  @Autowired  private RedisUtils redisUtils;  public String processRequest(HttpServletRequest request) {    // xml格式的消息数据    String respXml = null;    // 默认返回的文本消息内容    String respContent;    try {      // 调用parseXml方法解析请求消息      Map<String,String> requestMap = WeChatUtil.parseXml(request);       // 消息类型      String msgType = (String) requestMap.get(WeChatContant.MsgType);      String mes = null;      // 文本消息      if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_TEXT)) {        mes =requestMap.get(WeChatContant.Content).toString();        if(mes!=null&&mes.length()<2){          List<ArticleItem> items = new ArrayList<>();          ArticleItem item = new ArticleItem();          item.setTitle("照片墙");          item.setDescription("阿狸照片墙");          item.setPicUrl("http://changhaiwx.pagekite.me/photo-wall/a/iali11.jpg");          item.setUrl("http://changhaiwx.pagekite.me/page/photowall");          items.add(item);                    item = new ArticleItem();          item.setTitle("哈哈");          item.setDescription("一张照片");          item.setPicUrl("http://changhaiwx.pagekite.me/images/me.jpg");          item.setUrl("http://changhaiwx.pagekite.me/page/index");          items.add(item);                    item = new ArticleItem();          item.setTitle("小游戏2048");          item.setDescription("小游戏2048");          item.setPicUrl("http://changhaiwx.pagekite.me/images/2048.jpg");          item.setUrl("http://changhaiwx.pagekite.me/page/game2048");          items.add(item);                    item = new ArticleItem();          item.setTitle("百度");          item.setDescription("百度一下");          item.setPicUrl("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1505100912368&di=69c2ba796aa2afd9a4608e213bf695fb&imgtype=0&src=http%3A%2F%2Ftx.haiqq.com%2Fuploads%2Fallimg%2F170510%2F0634355517-9.jpg");          item.setUrl("http://www.baidu.com");          items.add(item);                    respXml = WeChatUtil.sendArticleMsg(requestMap, items);        }else if("我的信息".equals(mes)){          Map<String, String> userInfo = getUserInfo(requestMap.get(WeChatContant.FromUserName));          System.out.println(userInfo.toString());          String nickname = userInfo.get("nickname");          String city = userInfo.get("city");          String province = userInfo.get("province");          String country = userInfo.get("country");          String headimgurl = userInfo.get("headimgurl");          List<ArticleItem> items = new ArrayList<>();          ArticleItem item = new ArticleItem();          item.setTitle("你的信息");          item.setDescription("昵称:"+nickname+" 地址:"+country+" "+province+" "+city);          item.setPicUrl(headimgurl);          item.setUrl("http://www.baidu.com");          items.add(item);                    respXml = WeChatUtil.sendArticleMsg(requestMap, items);        }      }      // 图片消息      else if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_IMAGE)) {        respContent = "您发送的是图片消息!";        respXml = WeChatUtil.sendTextMsg(requestMap, respContent);      }      // 语音消息      else if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_VOICE)) {        respContent = "您发送的是语音消息!";        respXml = WeChatUtil.sendTextMsg(requestMap, respContent);      }      // 视频消息      else if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_VIDEO)) {        respContent = "您发送的是视频消息!";        respXml = WeChatUtil.sendTextMsg(requestMap, respContent);      }      // 地理位置消息      else if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_LOCATION)) {        respContent = "您发送的是地理位置消息!";        respXml = WeChatUtil.sendTextMsg(requestMap, respContent);      }      // 链接消息      else if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_LINK)) {        respContent = "您发送的是链接消息!";        respXml = WeChatUtil.sendTextMsg(requestMap, respContent);      }      // 事件推送      else if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_EVENT)) {        // 事件类型        String eventType = (String) requestMap.get(WeChatContant.Event);        // 关注        if (eventType.equals(WeChatContant.EVENT_TYPE_SUBSCRIBE)) {          respContent = "谢谢您的关注!";          respXml = WeChatUtil.sendTextMsg(requestMap, respContent);        }        // 取消关注        else if (eventType.equals(WeChatContant.EVENT_TYPE_UNSUBSCRIBE)) {          // TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复        }        // 扫描带参数二维码        else if (eventType.equals(WeChatContant.EVENT_TYPE_SCAN)) {          // TODO 处理扫描带参数二维码事件        }        // 上报地理位置        else if (eventType.equals(WeChatContant.EVENT_TYPE_LOCATION)) {          // TODO 处理上报地理位置事件        }        // 自定义菜单        else if (eventType.equals(WeChatContant.EVENT_TYPE_CLICK)) {          // TODO 处理菜单点击事件        }      }      mes = mes == null ? "不知道你在干嘛" : mes;      if(respXml == null)        respXml = WeChatUtil.sendTextMsg(requestMap, mes);      System.out.println(respXml);      return respXml;    } catch (Exception e) {      e.printStackTrace();    }    return "";      }}

微信工具类(只写了回复文本消息,和图文消息,其他的都是大同小异)

package com.wechat.util;import java.io.InputStream;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import javax.servlet.http.HttpServletRequest;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.wechat.bean.ArticleItem;/** * 请求校验工具类 *  * @author 32950745 * */public class WeChatUtil {    /**   * 验证签名   *    * @param signature   * @param timestamp   * @param nonce   * @return   */  public static boolean checkSignature(String signature, String timestamp, String nonce) {    String[] arr = new String[] { WeChatContant.TOKEN, timestamp, nonce };    // 将token、timestamp、nonce三个参数进行字典序排序    // Arrays.sort(arr);    sort(arr);    StringBuilder content = new StringBuilder();    for (int i = 0; i < arr.length; i++) {      content.append(arr[i]);    }    MessageDigest md = null;    String tmpStr = null;    try {      md = MessageDigest.getInstance("SHA-1");      // 将三个参数字符串拼接成一个字符串进行sha1加密      byte[] digest = md.digest(content.toString().getBytes());      tmpStr = byteToStr(digest);    } catch (NoSuchAlgorithmException e) {      e.printStackTrace();    }    content = null;    // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信    return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;  }  /**   * 将字节数组转换为十六进制字符串   *    * @param byteArray   * @return   */  private static String byteToStr(byte[] byteArray) {    String strDigest = "";    for (int i = 0; i < byteArray.length; i++) {      strDigest += byteToHexStr(byteArray[i]);    }    return strDigest;  }  /**   * 将字节转换为十六进制字符串   *    * @param mByte   * @return   */  private static String byteToHexStr(byte mByte) {    char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };    char[] tempArr = new char[2];    tempArr[0] = Digit[(mByte >>> 4) & 0X0F];    tempArr[1] = Digit[mByte & 0X0F];    String s = new String(tempArr);    return s;  }  private static void sort(String a[]) {    for (int i = 0; i < a.length - 1; i++) {      for (int j = i + 1; j < a.length; j++) {        if (a[j].compareTo(a[i]) < 0) {          String temp = a[i];          a[i] = a[j];          a[j] = temp;        }      }    }  }  /**   * 解析微信发来的请求(xml)   *    * @param request   * @return   * @throws Exception   */  @SuppressWarnings({ "unchecked"})  public static Map<String,String> parseXml(HttpServletRequest request) throws Exception {    // 将解析结果存储在HashMap中    Map<String,String> map = new HashMap<String,String>();    // 从request中取得输入流    InputStream inputStream = request.getInputStream();    // 读取输入流    SAXReader reader = new SAXReader();    Document document = reader.read(inputStream);    // 得到xml根元素    Element root = document.getRootElement();    // 得到根元素的所有子节点    List<Element> elementList = root.elements();    // 遍历所有子节点    for (Element e : elementList)      map.put(e.getName(), e.getText());    // 释放资源    inputStream.close();    inputStream = null;    return map;  }  public static String mapToXML(Map map) {    StringBuffer sb = new StringBuffer();    sb.append("<xml>");    mapToXML2(map, sb);    sb.append("</xml>");    try {      return sb.toString();    } catch (Exception e) {    }    return null;  }  private static void mapToXML2(Map map, StringBuffer sb) {    Set set = map.keySet();    for (Iterator it = set.iterator(); it.hasNext();) {      String key = (String) it.next();      Object value = map.get(key);      if (null == value)        value = "";      if (value.getClass().getName().equals("java.util.ArrayList")) {        ArrayList list = (ArrayList) map.get(key);        sb.append("<" + key + ">");        for (int i = 0; i < list.size(); i++) {          HashMap hm = (HashMap) list.get(i);          mapToXML2(hm, sb);        }        sb.append("</" + key + ">");      } else {        if (value instanceof HashMap) {          sb.append("<" + key + ">");          mapToXML2((HashMap) value, sb);          sb.append("</" + key + ">");        } else {          sb.append("<" + key + "><![CDATA[" + value + "]]></" + key + ">");        }      }    }  }  /**   * 回复文本消息   * @param requestMap   * @param content   * @return   */   public static String sendTextMsg(Map<String,String> requestMap,String content){        Map<String,Object> map=new HashMap<String, Object>();    map.put("ToUserName", requestMap.get(WeChatContant.FromUserName));    map.put("FromUserName", requestMap.get(WeChatContant.ToUserName));    map.put("MsgType", WeChatContant.RESP_MESSAGE_TYPE_TEXT);    map.put("CreateTime", new Date().getTime());    map.put("Content", content);    return mapToXML(map);  }   /**   * 回复图文消息   * @param requestMap   * @param items   * @return   */  public static String sendArticleMsg(Map<String,String> requestMap,List<ArticleItem> items){    if(items == null || items.size()<1){      return "";    }    Map<String,Object> map=new HashMap<String, Object>();    map.put("ToUserName", requestMap.get(WeChatContant.FromUserName));    map.put("FromUserName", requestMap.get(WeChatContant.ToUserName));    map.put("MsgType", "news");    map.put("CreateTime", new Date().getTime());    List<Map<String,Object>> Articles=new ArrayList<Map<String,Object>>();     for(ArticleItem itembean : items){      Map<String,Object> item=new HashMap<String, Object>();      Map<String,Object> itemContent=new HashMap<String, Object>();      itemContent.put("Title", itembean.getTitle());      itemContent.put("Description", itembean.getDescription());      itemContent.put("PicUrl", itembean.getPicUrl());      itemContent.put("Url", itembean.getUrl());      item.put("item",itemContent);      Articles.add(item);    }    map.put("Articles", Articles);    map.put("ArticleCount", Articles.size());    return mapToXML(map);  }  }

微信常量

public class WeChatContant {   //APPID  public static final String appID = "appid";  //appsecret  public static final String appsecret = "appsecret";  // Token  public static final String TOKEN = "zch";  public static final String RESP_MESSAGE_TYPE_TEXT = "text";  public static final Object REQ_MESSAGE_TYPE_TEXT = "text";  public static final Object REQ_MESSAGE_TYPE_IMAGE = "image";  public static final Object REQ_MESSAGE_TYPE_VOICE = "voice";  public static final Object REQ_MESSAGE_TYPE_VIDEO = "video";  public static final Object REQ_MESSAGE_TYPE_LOCATION = "location";  public static final Object REQ_MESSAGE_TYPE_LINK = "link";  public static final Object REQ_MESSAGE_TYPE_EVENT = "event";  public static final Object EVENT_TYPE_SUBSCRIBE = "SUBSCRIBE";  public static final Object EVENT_TYPE_UNSUBSCRIBE = "UNSUBSCRIBE";  public static final Object EVENT_TYPE_SCAN = "SCAN";  public static final Object EVENT_TYPE_LOCATION = "LOCATION";  public static final Object EVENT_TYPE_CLICK = "CLICK";    public static final String FromUserName = "FromUserName";  public static final String ToUserName = "ToUserName";  public static final String MsgType = "MsgType";  public static final String Content = "Content";  public static final String Event = "Event";  }

图文消息实体bean

public class ArticleItem {  private String Title;  private String Description;  private String PicUrl;  private String Url;  public String getTitle() {    return Title;  }  public void setTitle(String title) {    Title = title;  }  public String getDescription() {    return Description;  }  public void setDescription(String description) {    Description = description;  }  public String getPicUrl() {    return PicUrl;  }  public void setPicUrl(String picUrl) {    PicUrl = picUrl;  }  public String getUrl() {    return Url;  }  public void setUrl(String url) {    Url = url;  }  }

好了运行项目,在公众平台配置好url,个人订阅号完成.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表