zoukankan      html  css  js  c++  java
  • 微信公众号开发(一)前期 配置

    微信公众号开发步骤:
    一:有一个公众号,可以是测试公众号,也可以是客户提供的已经申请好的公众号
         申请测试公众号的网址:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
         申请步骤比较简单,这里就不多阐述了。
         我开发的主要是客户提供的公众号,一些特殊权限(支付)已经得到开通,可以直接使用,关于测试公众号的某些特殊权限,本人并没有经验。
     
    二:登录到微信公众平台进行开发配置,在登录时可能需要管理员授权,这个就自己联系你们的客户,管理员授权,你才能登录。
         登录网址:https://mp.weixin.qq.com/(微信公众平台--官网)

      
    管路员授权之后,我们就可以开始配置了,首先是“基本配置”
     
    首先,来到开发-->基本配置,这里我在初次开发的时候,不知道这里的url应该怎样填写,经过测试,这里的路径主要是一个外界能访问的路径。我的后台开发框架是springMVC,用户访问主要是通过controller,于是我新建了一个项目叫做WXTest,配置好springMVC之后写了一个controller,里面有一个方法叫Test,它的value值是"test",至于如何配置springMVC的项目,这里就不阐述了,如果有需要,我会单独写一篇文章阐述如何搭建一个简单的springNVC的框架。
    好了,配置好controller之后,我们可以通过本地访问:http://127.0.0.1:8080/WXTest/test  这样就可以访问到了,但是如何能让微信服务器访问我的controller,如果没有公网,可以通过花生壳的内网映射,如果有公网,可以直接通过公网的ip(开通了80端口的)访问,这里使用的是花生壳,壳域名就是http://uranusyiju.6655.la,通过花生的内网映射,我可以将其映射到我的8080端口,于是http://uranusyiju.6655.la就相当于我的http://127.0.0.1:8080,所以我这里的url配置就填写http://uranusyiju.6655.la/WXTest(项目名)/test(controller的方法路径),配置好url之后,至于token,主要是用于url的验证,你配置了之后,微信访问你的controller的时候会将这个数据发送于你的后台,你根据token判断是否是微信服务器在访问你,然后返回相应的数据,下面会提到,所以这里的token就是一个双方请求的标识而已,不必过于复杂。填写完token之后,下面的EncodingAESKey可以随机生成,然后确认没问题,点击提交,这里就会开始验证了,所以前期需要将你的框架搭建好,确保路径可以正确访问,以及返回正确的交互数据(如果你controller里的方法写得不对,则无法验证通过验证(下面会提到如何写controller的方法),验证通过了,最后,也是最重要的一个地方,请在外面选择“启用”。
     
    ***下面是controller的代码:
    @Controller
    public class WeixinController{
           
            @Resource
           UserSubscribeService userSubscribeService;
            @Resource
           UserUnSubscribeService userUnSubscribeService;
            @Resource
           UserScanQrCodeService userScanQrCodeService;
     
            // 唯藌的url、token接口设置(来自微信服务器的消息)
            @RequestMapping("/test" )
            @ResponseBody
            public void weixinUrlSet(HttpServletRequest request,
                        HttpServletResponse response) throws IOException {
                 System. out.println("进入test,微信的访问会有2种方式post以及get,get只是做url验证。 " );
                 
                  boolean isGet = request .getMethod().toLowerCase().equals("get");
                 
                  if (isGet ) {
                        System. out.println("request:" + request .toString());        
                         //get方法,一般用于微信服务器与本机服务器开发的基本配置(就是token验证,确定服务器是你的)
                        String str = access( request, response);
                         response.getWriter().write( str);
                 } else {
                         //post方法,一般是用户的事件处理(例如:关注/取消关注、点击按钮、发送消息....)
                        System. out.println("enter post" );
                        
                         try {
                                // 接收消息并返回消息
                               String str = acceptMessage( request, response); 
                               
                                      response.getWriter().write( str);               
                        } catch (IOException e ) {
                                e.printStackTrace();
                        }
                 }
           }
     
            /**
            * 验证URL真实性
            *
            * @author morning
            * @date 2015年2月17日 上午10:53:07
            * @param request
            * @param response
            * @return String
            * @throws NoSuchAlgorithmException
            * @throws UnsupportedEncodingException
            */
            private String access(HttpServletRequest request ,
                        HttpServletResponse response) {
                  // 验证URL真实性
                 System. out.println("进入验证access" );
                 String signature = request .getParameter("signature"); // 微信加密签名
                 String timestamp = request .getParameter("timestamp"); // 时间戳
                 String nonce = request.getParameter( "nonce");// 随机数
                 String echostr = request.getParameter( "echostr");// 随机字符串
     
                 List<String> params = new ArrayList<String>();
                 //WeixinStaticData. TOKEN就是配置时的token
                  params.add(WeixinStaticData. TOKEN);
                  params.add( timestamp);
                  params.add( nonce);
     
                  // 1. 将token、timestampnonce三个参数进行字典序排序
                 Collections. sort(params, new Comparator<String>() {
                         @Override
                         public int compare(String o1, String o2) {
                                return o1 .compareTo(o2);
                        }
                 });
     
                  // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
                 String str = params.get(0) + params.get(1) + params.get(2);
                 MessageDigest crypt;
                  try {
                         crypt = MessageDigest. getInstance("SHA-1");
                         crypt.reset();
     
                         try {
                                crypt.update( str.getBytes( "UTF-8"));
     
                               String temp = WeixinTool. batySHA1(crypt.digest());
     
                                if (temp .equals(signature )) {
                                     System. out.println("成功返回 echostr:" + echostr);
                                      return echostr ;
                               } else {
                                     System. out.println("失败 认证" );
                               }
                        } catch (UnsupportedEncodingException e1 ) {
                                // TODO Auto-generated catch block
                                e1.printStackTrace();
                        }
     
                 } catch (NoSuchAlgorithmException e1 ) {
                         // TODO Auto-generated catch block
                         e1.printStackTrace();
                 }
                  return null ;
           }
     
            private String acceptMessage(HttpServletRequest request,
                        HttpServletResponse response) throws IOException {
                 Map<String, String> reqMap = MessageUtil. parseXml(request);
                 
                 System. out.println("reqMap:" +reqMap .toString());
     
                 String fromUserName = reqMap .get("FromUserName" );
                 String toUserName = reqMap .get("ToUserName" );
                 String msgType = reqMap.get( "MsgType");
     
                 BaseMsg msg = null;// 要发送的消息
     
                  // 事件推送
                  if (msgType .equals(ReqType.EVENT)) {
                         // 事件类型
                        String eventType = reqMap .get("Event" );
     
                         // 二维码事件
                        String ticket = reqMap.get( "Ticket");
                         if (ticket != null) {
                               String eventKey = reqMap.get( "EventKey");
                               QrCodeEvent event = new QrCodeEvent(eventKey , ticket);
                               buildBasicEvent( reqMap, event);
                                msg = handleQrCodeEvent( event);
                        }
                         // 关注
                         if (eventType .equals(EventType.SUBSCRIBE)) {
                                //根据reqMap 可以判断用户是否扫带有有参数的二维码
                               BaseEvent event = new BaseEvent();
                               buildBasicEvent( reqMap, event);
                                msg = handleSubscribe( event, reqMap);
                        
                        }
                         // 取消关注
                         else if (eventType .equals(EventType.UNSUBSCRIBE)) {
                               BaseEvent event = new BaseEvent();
                               buildBasicEvent( reqMap, event);
                                msg = handleUnsubscribe( event);
                        }
                         // 点击菜单拉取消息时的事件推送
                         else if (eventType .equals(EventType.CLICK)) {
                               System. out.println("点击菜单拉取消息时的事件推送" );
                               String eventKey = reqMap.get( "EventKey");
                               MenuEvent event = new MenuEvent(eventKey );
                               buildBasicEvent( reqMap, event);
                                msg = handleMenuClickEvent( event);
                        }
                         // 点击菜单跳转链接时的事件推送
                         else if (eventType .equals(EventType.VIEW)) {
                               System. out.println("点击菜单跳转链接时的事件推送" );
                               String eventKey = reqMap.get( "EventKey");
                               MenuEvent event = new MenuEvent(eventKey );
                               System. out.println("event:" +event .toXml().toString());
                               buildBasicEvent( reqMap, event);
                               
                                msg = handleMenuViewEvent( event);
                        }
                         // 上报地理位置事件
                         else if (eventType .equals(EventType.LOCATION)) {
                                double latitude = Double.parseDouble(reqMap.get("Latitude"));
                                double longitude = Double.parseDouble(reqMap.get("Longitude"));
                                double precision = Double.parseDouble(reqMap.get("Precision"));
                               LocationEvent event = new LocationEvent(latitude , longitude,
                                             precision);
                               buildBasicEvent( reqMap, event);
                                msg = handleLocationEvent( event);
                        }
     
                 } else {// 接受普通消息
     
                         // 文本消息
                         if (msgType .equals(ReqType.TEXT)) {
                               String content = reqMap.get( "Content");
                               TextReqMsg textReqMsg = new TextReqMsg(content);
                               buildBasicReqMsg( reqMap, textReqMsg);
                                msg = handleTextMsg( textReqMsg);
                        }
                         // 图片消息
                         else if (msgType .equals(ReqType.IMAGE)) {
                               String picUrl = reqMap.get( "PicUrl");
                               String mediaId = reqMap.get( "MediaId");
                               ImageReqMsg imageReqMsg = new ImageReqMsg(picUrl, mediaId);
                               buildBasicReqMsg( reqMap, imageReqMsg);
                                msg = handleImageMsg( imageReqMsg);
                        }
                         // 音频消息
                         else if (msgType .equals(ReqType.VOICE)) {
                               String format = reqMap.get( "Format");
                               String mediaId = reqMap.get( "MediaId");
                               String recognition = reqMap .get("Recognition" );
                               VoiceReqMsg voiceReqMsg = new VoiceReqMsg(mediaId, format,
                                             recognition);
                               buildBasicReqMsg( reqMap, voiceReqMsg);
                                msg = handleVoiceMsg( voiceReqMsg);
                        }
                         // 视频消息
                         else if (msgType .equals(ReqType.VIDEO)) {
                               String thumbMediaId = reqMap .get("ThumbMediaId" );
                               String mediaId = reqMap.get( "MediaId");
                               VideoReqMsg videoReqMsg = new VideoReqMsg(mediaId, thumbMediaId);
                               buildBasicReqMsg( reqMap, videoReqMsg);
                                msg = handleVideoMsg( videoReqMsg);
                        }
                         // 地理位置消息
                         else if (msgType .equals(ReqType.LOCATION)) {
                                double locationX = Double.parseDouble(reqMap.get("Location_X"));
                                double locationY = Double.parseDouble(reqMap.get("Location_Y"));
                                int scale = Integer.parseInt (reqMap .get("Scale" ));
                               String label = reqMap.get( "Label");
                               LocationReqMsg locationReqMsg = new LocationReqMsg(locationX,
                                             locationY, scale , label );
                               buildBasicReqMsg( reqMap, locationReqMsg);
                                msg = handleLocationMsg( locationReqMsg);
                        }
                         // 链接消息
                         else if (msgType .equals(ReqType.LINK)) {
                               String title = reqMap.get( "Title");
                               String description = reqMap .get("Description" );
                               String url = reqMap.get( "Url");
                               LinkReqMsg linkReqMsg = new LinkReqMsg(title, description, url );
                               buildBasicReqMsg( reqMap, linkReqMsg);
                                msg = handleLinkMsg( linkReqMsg);
                        }
     
                 }
     
                  if (msg == null) {
                         // 回复空串是微信的规定,代表不回复
                         return "" ;
                 }
     
                  msg.setFromUserName( toUserName);
                  msg.setToUserName( fromUserName);
                  return msg .toXml();
           }
           
           
            /*******************************************下面为处理每个请求的具体逻辑入口*******************************/
     
            /**
            * 处理文本消息
            */
            protected BaseMsg handleTextMsg(TextReqMsg msg ) {
                  return handleDefaultMsg(msg );
           }
     
            /**
            * 处理图片消息
            */
            protected BaseMsg handleImageMsg(ImageReqMsg msg ) {
                  return handleDefaultMsg(msg );
           }
     
            /**
            * 处理语音消息
            */
            protected BaseMsg handleVoiceMsg(VoiceReqMsg msg ) {
                  return handleDefaultMsg(msg );
           }
     
            /**
            * 处理视频消息
            */
            protected BaseMsg handleVideoMsg(VideoReqMsg msg ) {
                  return handleDefaultMsg(msg );
           }
     
            /**
            * 处理地理位置消息
            */
            protected BaseMsg handleLocationMsg(LocationReqMsg msg) {
                  return handleDefaultMsg(msg );
           }
     
            /**
            * 处理链接消息
            */
            protected BaseMsg handleLinkMsg(LinkReqMsg msg ) {
                  return handleDefaultMsg(msg );
           }
     
            /**
            * 处理扫描带参数二维码事件
            */
            protected BaseMsg handleQrCodeEvent(QrCodeEvent event ) {
                 System. out.println("处理扫描带参数二维码事件" );
                 System. out.println("event:" +event .toXml());
                  userScanQrCodeService.handleScanQrCode();
                  return handleDefaultEvent(event );
           }
     
            /**
            * 处理上报地理位置事件
            */
            protected BaseMsg handleLocationEvent(LocationEvent event) {
                  return handleDefaultEvent(event );
           }
     
            /**
            * 处理点击菜单拉取消息时的事件推送
            */
            protected BaseMsg handleMenuClickEvent(MenuEvent event) {
                  return handleDefaultEvent(event );
           }
     
            /**
            * 处理点击菜单跳转链接时的事件推送
            */
            protected BaseMsg handleMenuViewEvent(MenuEvent event ) {
                  return handleDefaultEvent(event );
           }
     
            /**
            * 处理关注事件
            * 默认不回复
            */
            protected BaseMsg handleSubscribe(BaseEvent event , Map<String,String> reMap) {
                 System. out.println("用户关注======" );
                  userSubscribeService.handleSubscribeService(event ,reMap );
                 String msg = userSubscribeService.displayAutoReturn();
                  return new TextMsg(msg);
           }
     
            /**
            * 处理取消订阅事件 <br>
            * 默认不回复
            */
            protected BaseMsg handleUnsubscribe(BaseEvent event ) {
                 System. out.println("用户取消关注======" );
                  userUnSubscribeService.handleUnSubscribe(event );
                  return null ;
           }
     
            /**
            * 处理消息的默认方式 <br>
            * 如果不重写该方法,则默认不返回任何消息
            */
            protected BaseMsg handleDefaultMsg(BaseReqMsg msg ) {
                  return null ;
           }
     
            /**
            * 设置处理事件的默认方式 <br>
            * 如果不重写该方法,则默认不返回任何消息
            */
            protected BaseMsg handleDefaultEvent(BaseEvent event ) {
                  return null ;
           }
     
            /**
            * 为事件普通消息对象添加基本参数 <br>
            * 参数包括:MsgId、MsgType、FromUserName、ToUserName和CreateTime
            */
            private void buildBasicReqMsg(Map<String, String> reqMap, BaseReqMsg reqMsg) {
                 addBasicReqParams( reqMap, reqMsg);
                  reqMsg.setMsgId( reqMap.get( "MsgId"));
           }
     
            /**
            * 为事件推送对象添加基本参数 <br>
            * 参数包括:Event、MsgType、FromUserName、ToUserName和CreateTime
            */
            private void buildBasicEvent(Map<String, String> reqMap, BaseEvent event) {
                 addBasicReqParams( reqMap, event);
                  event.setEvent( reqMap.get( "Event"));
           }
     
            /**
            * 为请求对象添加基本参数,包括MsgType、FromUserName、ToUserName和CreateTime <br>
            * 请求对象包括普通消息和事件推送
            */
            private void addBasicReqParams(Map<String, String> reqMap, BaseReq req) {
                  req.setMsgType( reqMap.get( "MsgType"));
                  req.setFromUserName( reqMap.get( "FromUserName"));
                  req.setToUserName( reqMap.get( "ToUserName"));
                  req.setCreateTime(Long. parseLong(reqMap.get("CreateTime")));
           }
    }
     
    上面的代码很多,其实浏览一下能知道大概意思就可以了。
    ok,现在配置以及初步处理微信请求都已经准备好了,还有很多其他配置,在需要的时候会提到,下面就开始进入正式的开发了.....
     
     
     
     
     
  • 相关阅读:
    OO第四单元总结
    OO第三单元总结
    OO第二单元作业总结
    OO第一次总结
    OO第四单元总结
    OO第三单元总结
    OO第二单元总结
    OO第一单元总结
    使用pushplus+python实现亚马逊到货消息推送微信
    OO第四次博客作业
  • 原文地址:https://www.cnblogs.com/xyabk/p/5776317.html
Copyright © 2011-2022 走看看