微信公众号开发(一)前期 配置
发布日期:2021-08-13 04:05:44 浏览次数:28 分类:技术文章

本文共 11156 字,大约阅读时间需要 37 分钟。

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

  
管路员授权之后,我们就可以开始配置了,首先是“基本配置”
 
首先,来到开发-->基本配置,这里我在初次开发的时候,不知道这里的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

转载地址:https://blog.csdn.net/weixin_30675247/article/details/99012645 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:WebRTC学习之 Intel® Collaboration Suite for WebRTC源码流程解读
下一篇:unity引擎面板管理相关方法

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月24日 07时16分49秒