微信公众号开发(一)前期 配置

微信公众号开发步骤:
一:有一个公众号,可以是测试公众号,也可以是客户提供的已经申请好的公众号
     申请测试公众号的网址: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,现在配置以及初步处理微信请求都已经准备好了,还有很多其他配置,在需要的时候会提到,下面就开始进入正式的开发了.....
 
 
 
 
 

转载于:https://www.cnblogs.com/xyabk/p/5776317.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值