当前位置 博文首页 > 高远的博客:java微信开发API解析(六)-综合运用(消息处理、自

    高远的博客:java微信开发API解析(六)-综合运用(消息处理、自

    作者:[db:作者] 时间:2021-09-06 22:48

    java微信开发API解析(六)

    全局说明

    * 详细说明请参考前两篇文章。
    

    本文说明

    * 本文主要是对前面学习的知识进行综合整合。
    * 我们对需要的bean、工具类、xml、file进行必要的包装。
    * 我们构建一个可以直接使用的Java微信应用。
    * 文后包含该部分效果的测试微信公众号
    * 文后包含构建好的源码供下载
    

    bean的构建

    • public class Access_token,获取Access_token对应的bean。

      private String access_token;
      private String expires_in;
      
    • public class BaseMsg,所有消息共有成员变量bean。

      private String ToUserName;
      private String FromUserName;
      private long CreateTime;
      private String MsgType;
      
    • public class TextMsg extends BaseMsg,文本消息bean。

      private String Content;
      
    • public class Group,分组所需要的成员变量bean。

      private int id;
      private String name;
      private int count;
      private String openid;
      private String to_groupid;
      private String groupid;
      

    工具类的构建

    • public class AccessTokenUtils,该工具类前文已经详细说明过了,在此处没有改动。
    • public class GlobalParamsUtils,该工具类存储了全局常量,包括APPID、SECERT、token等;以及微信服务器响应的消息类型(类型较多,可以直接查看源码,不再此处列出)。
    • public class GroupUtils ,包括对分组的各种操作。除了上一篇文章所说的对用户分组,还有一个保存用户信息的两个工具方法,如下

      public class GroupUtils {
          private static final String TAG = "GroupUtils";
      
          /*
           * 该方法测试将用户移动到指定分组
           */
          public static String updateGroup(String openid, String to_groupid) {
              ...
          }
      
          public static boolean existUser(String openid) {
              try {
                  BufferedReader dr = new BufferedReader(new InputStreamReader(
                          new FileInputStream(new File("user.txt"))));
                  String line = dr.readLine();
                  while (line != null) {
                      if (openid.equals(line))
                          return true;
                      line = dr.readLine();
                  }
                  dr.close();
                  return false;
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
                  return false;
              }
          }
      
          public static boolean AddGroup(String openid) {
              try {
                  File file = new File("user.txt");
                  if (!file.exists())
                      file.createNewFile();
                  BufferedWriter dw = new BufferedWriter(new OutputStreamWriter(
                          new FileOutputStream(file, true)));
                  dw.write(openid);
                  dw.newLine();
                  dw.flush();
                  dw.close();
                  return true;
              } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
                  return false;
              }
          }
      
          @Test
          public void Test1() {
              AddGroup("asdas");
          }
      }
      
    • public class MyHttpUtils,关于http的请求的简单封装。

    • public class SHAUtils,对sha加密的抽取。
    • public class XmlUtils ,对xml处理的工具抽取,如下

          package com.gist.utils;
      
          import java.io.InputStream;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
      
          import org.dom4j.Document;
          import org.dom4j.DocumentException;
          import org.dom4j.Element;
          import org.dom4j.io.SAXReader;
          import org.junit.Test;
      
          import com.gist.bean.TextMsg;
          import com.thoughtworks.xstream.XStream;
      
          /**
           * @author 高远</n>
           * 编写日期   2016-4-24下午2:28:07</n>
           * 邮箱  wgyscsf@163.com</n>
           * 博客  http://blog.csdn.net/wgyscsf</n>
           * TODO</n>
           */
          public class XmlUtils {
              private static final String TAG = "XmlUtils";
      
              /*
               * 解析用户发送过来的请求。将请求的xml全部封装到map里面
               */
              public static Map<String, String> handleXmlMsg(InputStream is) {
                  Map<String, String> map = new HashMap<String, String>();
                  try {
                      SAXReader saxReader=new SAXReader();
                      Document document = saxReader.read(is);
                      Element root = document.getRootElement();
                      List<Element> elements = root.elements();
                      for (Element e : elements) {
                          map.put(e.getName(), e.getText());
                      }
                      elements = null;
                      root = null;
                      document = null;
                      return map;
                  } catch (DocumentException e) {
                      e.printStackTrace();
                  }
                  return null;
              }
      
              /**
               * TODO
               */
              public static String str2Xml(TextMsg textMsg) {
                  XStream xStream=new XStream();
                  xStream.alias("xml", TextMsg.class);
                  String xmlStr = xStream.toXML(textMsg);
                  return xmlStr;
              }
              @Test
              public void Test() {
                  // 我们封装一个回复文本的信息.
                  TextMsg textMsg = new TextMsg();
                  textMsg.setFromUserName("from");
                  textMsg.setToUserName("to");
                  textMsg.setMsgType(GlobalParamsUtils.MSGTYPE_TEXT);
                  String content = "默认回复消息.";
                  textMsg.setContent(content);
                  textMsg.setCreateTime(System.currentTimeMillis());
                  System.out.println(str2Xml(textMsg));
              }
          }
      

    servlet的构建以及业务层service的构建

    • public class CoreServlet extends HttpServlet,该方法改动很小,其中的POST请求如下

      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp)
              throws ServletException, IOException {
          // 特别注意,req.getInputStream()只能获取一次,并且只能读取一次。如果想要多次读取,需要另外想办法。
          // 设置编码
          req.setCharacterEncoding("utf-8");
          resp.setContentType("text/html;charset=utf-8");
          CoreService coreService = new CoreService();
          /*
           * 获取用户发送过来的消息
           */
          InputStream is = req.getInputStream();
      
          String reqXml = coreService.handleRequest(is);// 接收处理过之后的xml
          /*
           * 给用户回复消息
           */
          PrintWriter writer = resp.getWriter();
          writer.print(reqXml);
          writer.flush();
      }
      
    • public class CoreService,业务核心类,如下

      package com.gist.service;
      
      import java.io.InputStream;
      import java.util.Map;
      
      import com.gist.bean.TextMsg;
      import com.gist.utils.GlobalParamsUtils;
      import com.gist.utils.GroupUtils;
      import com.gist.utils.XmlUtils;
      
      /**
       * @author 高远</n>
       * 编写日期   2016-4-24下午2:10:32</n>
       * 邮箱  wgyscsf@163.com</n>
       * 博客  http://blog.csdn.net/wgyscsf</n>
       * TODO</n>
       */
      public class CoreService {
          // private static final String TAG = "CoreService";
      
          public String handleRequest(InputStream is) {
              boolean flag = false;// 设置一个标记,供下面分组用
              // 用户发送过来消息是xml格式的。虽然消息类型繁多,但是格式基本固定(参看资料包中的“请求资料.txt”)。我们使用xstram对其进行xml解析。
              Map<String, String> handleXmlMsg = XmlUtils.handleXmlMsg(is);
              /*
               * 我们查看资料包中的“请求资料.txt”可以发现,所有的请求都包括以下字段
               * <ToUserName><![CDATA[toUser]]></ToUserName>
               * <FromUserName><![CDATA[fromUser]]></FromUserName>
               * <CreateTime>1348831860</CreateTime>
               * <MsgType><![CDATA[text]]></MsgType>
               * 特别的,对于关注和取消关注、自定义菜单,还有一个共有的字段“Event
               * ”,并且它们的“MsgType”内容全部都是“event”(需要仔细观察
               * )。请参考GlobalParamsUtils中关于该部分参数的设置。
               */
              /*
               * 第一步,我们先获取所有事件共有的参数
               */
              String ToUserName = handleXmlMsg.get("ToUserName");
              String FromUserName = handleXmlMsg.get("FromUserName");
              String CreateTime = handleXmlMsg.get("CreateTime");
              String MsgType = handleXmlMsg.get("MsgType");
      
              // 我们封装一个回复文本的信息.
              TextMsg textMsg = new TextMsg();
              textMsg.setFromUserName(ToUserName);
              textMsg.setToUserName(FromUserName);
              textMsg.setMsgType(GlobalParamsUtils.MSGTYPE_TEXT);
              String content = "默认回复消息.wgyscsf";
      
              // 我们在这里测试一下用户自动分组(强制选择)
      
              boolean exist = GroupUtils.existUser(FromUserName);
      
              if (!exist) {
      
                  String text = handleXmlMsg.get("Content");
                  if (text.equals("1")) {
      
                      content = GroupUtils.updateGroup(FromUserName, "101");
                      GroupUtils.AddGroup(FromUserName);
                  } else if (text.equals("2")) {
      
                      content = GroupUtils.updateGroup(FromUserName, "102");
                      GroupUtils.AddGroup(FromUserName);
                  } else {
      
                      content = "请先选择分组(选择对应数字)<\n>:1、开发人员;2、普通用户";
                  }
                  textMsg.setContent(content);
                  textMsg.setCreateTime(System.currentTimeMillis());
                  String xmlStr = XmlUtils.str2Xml(textMsg);
                  return xmlStr;
              }
      
      
              /*
               * 第二步,根据MsgType判断用户的请求类型。两大类:普通消息、事件推送
               */
              // 推送消息
              if (MsgType.equals(GlobalParamsUtils.MSGTYPE_EVENT)) {
                  // 这里面在细节判断是何种推送事件
                  String EVENT = handleXmlMsg.get("Event");
      
                  if (EVENT.equals(GlobalParamsUtils.EVENT_SUBSCRIBE)) {
                      // 用户关注
                      content = "欢迎您的关注。";
                  } else if (EVENT.equals(GlobalParamsUtils.EVENT_UNSUBSCRIBE)) {
                      // 取消关注
                      content = "取消关注。";
                  } else if (EVENT.equals(GlobalParamsUtils.EVENT_SCAN)) {
                      // 扫描二维码
                      content = "扫描二维码。";
                  } else if (EVENT.equals(GlobalParamsUtils.EVENT_LOCATION)) {
                      // 地理位置
                      content = "地理位置。";
                  } else if (EVENT.equals(GlobalParamsUtils.EVENT_CLICK)) {
                      // click事件
                      content = "click事件。";
                  } else if (EVENT.equals(GlobalParamsUtils.EVENT_VIEW)) {
                      // view事件
                      content = "view事件。";
                  }
      
              } else {
                  // 普通消息
                  if (MsgType.equals(GlobalParamsUtils.MSGTYPE_TEXT)) {
                      // 普通文本
                      content = "普通文本。";
                  } else if (MsgType.equals(GlobalParamsUtils.MSGTYPE_IMAGE)) {
                      // 图片消息
                      content = "图片消息。";
                  } else if (MsgType.equals(GlobalParamsUtils.MSGTYPE_VOICE)) {
                      // 语音消息
                      content = "语音消息。";
                  } else if (MsgType.equals(GlobalParamsUtils.MSGTYPE_VIDEO)) {
                      // 视频消息
                      content = "视频消息。";
                  } else if (MsgType.equals(GlobalParamsUtils.MSGTYPE_SHORTVIDEO)) {
                      // 小视频消息
                      content = "小视频消息。";
                  } else if (MsgType.equals(GlobalParamsUtils.MSGTYPE_LOCATION)) {
                      // 地理位置消息
                      content = "地理位置消息。";
                  } else if (MsgType.equals(GlobalParamsUtils.MSGTYPE_LINK)) {
                      // 链接消息
                      content = "链接消息。";
                  }
              }
              textMsg.setContent(content);
              textMsg.setCreateTime(System.currentTimeMillis());
              String xmlStr = XmlUtils.str2Xml(textMsg);
              return xmlStr;
      
          }
      }
      

    测试的微信号二维码(包含上述所说的效果)

    效果测试微信号
    这是平时写的一些技术文章的微信公众号,欢迎关注:
    技术学习

    源码下载

    http://download.csdn.net/detail/wgyscsf/9501213

    cs
    下一篇:没有了