反射在微信公众平台开发中的应用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zhupanlinch/article/details/102693887

1、开发背景

在微信公众号开发的时候,我们都会去解析微信消息,然后根据不同的消息类型做对应的操作。下面是一段微信的消息体:

<xml>

<ToUserName><![CDATA[toUser]]></ToUserName>

<FromUserName><![CDATA[fromUser]]></FromUserName>

<CreateTime>1348831860</CreateTime>

<MsgType><![CDATA[MsgType]]></MsgType>

<MsgId>1234567890123456</MsgId>

</xml>

这里的MsgType有8种,分别是text、event。这么多中消息类型,怎么办呢?if...else,switch?都可以处理,看起来It's too simple。

那么问题来了,还有事件消息event。这个消息有关注,取关,上传地理位置以及自定义菜单等。看消息体:

<xml>

<ToUserName><![CDATA[toUser]]></ToUserName>

<FromUserName><![CDATA[FromUser]]></FromUserName>

<CreateTime>123456789</CreateTime>

<MsgType><![CDATA[event]]></MsgType>

<Event><![CDATA[subscribe]]></Event>

</xml>

事件消息都是event类型,具体的事件(点击了不同的按钮)对应一个Event,在自定义菜单的时候,那这个Event就有N种了。如果都用分支结构去写,那就有点尴尬了。所以呢,为了解决这种尴尬,下面引入一个概念——反射。

2、反射

反射是什么呢?说起这个概念,笔者表示一脸懵逼。我不记得,下面请看一几个例子。

2.1通过一个对象获得完整的包名和类名

public static void main(String[] args) {
Demo demo=new Demo();
   System.out.println(demo.getClass().getName());
}


2.2实例化Class类对象

Class<?> demo1=null;

demo1=Class.forName("com.example.bean.Demo");

注意:还有很多示例,请移驾到baidu.com

在你百度了一下你就会发现,我的两个简单的例子也是copy过来的。不过还是要总结一下反射有什么用:


在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

 

看完了上面这一段解释,是不是一脸懵逼,没关系,接着看,从例子中理解反射的作用。


3、反射在微信公众平台开发中的应用

/**
* 微信事件    
**/
public interface
WechatEventCenter {

/**
    * @功能描述: 微信默认回复
    */
   public BaseWechatMsg defaultEvent();

   /**
    * @功能描述: 文本消息
    */
   public BaseWechatMsg text();

   /**
    * @功能描述: 位置消息
    */
   public BaseWechatMsg location();

   /**
    * @功能描述: 语音消息
    */
   public BaseWechatMsg voice();

   /**
    * @功能描述: <p>事件消息</p>
    */
   public BaseWechatMsg event();

   /**
    * @功能描述: <p>用户未关注时,进行关注后的事件推送</p>
    * @return
    */
   public BaseWechatMsg subscribe();

   /**
    * @功能描述: 按钮1, 创建按钮时对应的EventKey为方法名
    * 所以这里的方法名看着有点怪啊,没有按java的命名规范来,
    * 你也可以按照自己的喜好来定义

    */
   public BaseWechatMsg EVENT_HOME();

}
/**
* 微信接入入口
**/
@RequestMapping(value="index")
@ResponseBody
public String wechat(HttpServletRequest request, HttpServletResponse response,
String signature, String timestamp, String nonce, String echostr) {
String result = "";
   String method = request.getMethod();
   if("GET".equals(method)){//接入验证
       return echostr;//直接返回echostr便接入成功了,此处省略了解密验证
   } else {//消息处理
       result = dopost(request);
   }
return result;
}

接入成功了之后了,下面就到了重点了,直接上代码:

private String dopost(HttpServletRequest request){

BaseWechatMsg wechatMsg;
  try {
String sReqData = WechatUtils.convertStreamToString(request.getInputStream());
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
     DocumentBuilder db = dbf.newDocumentBuilder();
     StringReader sr = new StringReader(sReqData);
     InputSource is = new InputSource(sr);
     Document document = db.parse(is);
     Element root = document.getDocumentElement();
     String FromUserName = root.getElementsByTagName(HqWechatConstant.FromUserName).item(0).getTextContent();
     System.out.println("用户: "+FromUserName+" 进入wechat. ");
     System.out.println("用户消息为:\r\n" + sReqData);
     String msgType = root.getElementsByTagName(HqWechatConstant.MsgType).item(0).getTextContent();
     wechatEventCenter.setRoot(root);//参数注入
        //根据事件类型获取要执行的方法
     Method method = wechatEventCenter.getClass().getMethod(msgType);
        //用反射根据方法名调用方法

     wechatMsg = (BaseWechatMsg) method.invoke(wechatEventCenter);
  } catch (Exception e) {
//调用默认方法
       wechatMsg = (BaseWechatMsg) wechatEventCenter.defaultEvent();
       e.printStackTrace();
  } finally {
}
System.out.println("回复消息为:\r\n"+wechatMsg);
  return wechatMsg.toString();

}

这里的处理就用到了反射了,就是下面这两行代码:

Method method = wechatEventCenter.getClass().getMethod(msgType);

wechatMsg = (BaseWechatMsg) method.invoke(wechatEventCenter);

这样整个过程就完成了,在处理事件消息的时候也是一样的根据事件的EventKey去调用对应的方法就OK了,这里就不赘述了。

4、总结

在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

  

仅供参考,不足之处还请见谅,欢迎指正!


文末福利,关注java工会后台回复

回复【视频】:100G+免费学习视频
回复【书籍真多】:1000+册免费编程电子书
回复【加群】:java技术学习交流群,阿里大神和你聊技术

640?wx_fmt=png

猜你喜欢

转载自blog.csdn.net/zhupanlinch/article/details/102693887