微信公众好开发流程 Java
1、申请账号
公众号分为服务号、企业号、订阅号,每个类型所对应的接口是不同的
公众号接口权限说明
不同的公众号类型具备不同的接口权限,具体如下表: 请注意:
1)、微博认证视作未认证,因此微博认证的公众号不会拥有微信认证公众号特有的接口。
2)、微信认证分为资质认证和名称认证两部分,只需要资质认证通过,就可获得接口。
对于我们个人开发尝试而言,个人是不能够认证的,所以只能有一点点接口可以调用
但是公众号提供了测试公众号,
直接体验和测试公众平台所有高级接口
2、对公众号进行必要的配置
1)、个人开发的过程中,我们要经常进行调试,但是我们的电脑基本都是没有独立的外网IP,我们可以通过第三方的工具进行内网映射,将外网地址映射到本地电脑,只要输入外网地址就可以找到本地电脑
以下是我使用工程中的心得,每个都会提供免费的域名映射内网地址
nat123
页面古板,且一步步的诱惑充值,免费开通后
第一步<Java>需要使用80端口?充值8元:不能使用80端口<Java>然后为了使用80端口,充值8元
第二步<Java>需要使用自定义域名?至少充值30元:不能使用自定义域名<Java> 卒
花生壳
页面美观,开通内网映射需要充值8元开通,开通后也是不能使用自定义域名的,但是没有诱导的过程
NATAPP
页面简单,可开通免费的隧道使用内网映射,不过为了使用自定义域名,开通VIP1
推荐使用这款,可以使用自定义域名,因为微信把大部分内网映射提供的域名加入了黑名单,使用的时候可能会报(该网页不是微信官方的网页,可能不安全,影响体验)
具体使用教程可参考
https://natapp.cn/article
由于前期个人需要,申请了域名并通过了备案
2) 微信配置
图1 微信基本配置
图2 启用微信网页授权
图3 修改为自己的域名
3 Java 代码
设置微信网关,项目中所有和微信交互的全都要通过该接口
/**
* WxGateway 微信转发网关
*/
@Controller
@RequestMapping("/gateway")
public class WxGateway {
private static final Logger logger = LoggerFactory
.getLogger(WxGateway.class);
@Autowired
private WxMpConfigStorage wxMpConfigStorage;
@Autowired
private WxMpService wxMpService;
@Autowired
private WxMpMessageRouter wxMpMessageRouter;
@Autowired
private IWxMpService iWxMpService;
@Autowired
private IUserTokenService iUserTokenService;
Gson gson = new Gson();
@Value("${charset}")
private String charset;
/**
* 微信公众号主网关,负责处理所有和微信公众号信息交互
*/
@RequestMapping("/main")
public void gateway(HttpServletRequest request, HttpServletResponse response, String xml)
throws IOException {
response.setCharacterEncoding(charset);
logger.debug("接收到消息......");
// 读取输入流
Map<String, String> reqParam = getAllRequestParam(request);
String signature = request.getParameter("signature");
String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp");
// 验签
if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
// 消息签名不正确,说明不是公众平台发过来的消息
logger.info("非法请求");
response.getWriter().println("非法请求");
response.getWriter().close();
return;
}
String echostr = request.getParameter("echostr");
if (StringUtils.isNotBlank(echostr)) {
// 说明是一个仅仅用来验证的请求,回显echostr
logger.info("echostr:" + echostr);
response.getWriter().println(echostr);
response.getWriter().close();
return;
}
String encryptType = request.getParameter("encrypt_type");
// 加密类型
encryptType = StringUtils.isBlank(encryptType) ? "raw" : encryptType;
if ("raw".equals(encryptType)) {
// 明文传输的消息
String xmlStr = StringUtil.convertStreamToString(request.getInputStream());
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(xmlStr);
logger.info("{}", xmlStr);
iWxMpService.saveInMsg(inMessage);
WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
UserToken userToken = iUserTokenService.findByOpenId(inMessage.getFromUser());
if(userToken != null){
if (outMessage != null) {
long msgId = 0;
if (null != inMessage.getMsgId()) {
msgId = inMessage.getMsgId();
}
iWxMpService.saveOutMsg(outMessage, msgId);
// 说明是同步回复的消息
// 将xml写入HttpServletResponse
response.getWriter().write(outMessage.toXml());
} else {
// 说明是异步回复的消息,直接将空字符串写入HttpServletResponse
response.getWriter().write("");
}
}else {
//String reply = "<a href=\"info/login\">" + "请先绑定账号" + "</a>";
response.getWriter().write(outMessage.toXml());
}
response.getWriter().close();
return;
}
if ("aes".equals(encryptType)) {
// 是aes加密的消息
String msgSignature = request.getParameter("msg_signature");
WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(
request.getInputStream(), wxMpConfigStorage, timestamp,
nonce, msgSignature);
WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
response.getWriter().write(
outMessage.toEncryptedXml(wxMpConfigStorage));
/**
* 微信服务器发送三次重复的排重问题解决流程:
a.得到数据response.getWriter();
b.得到数据request下的所有数据--->写入一个HashMap中
c.使用response的writer返回一个空白,并且关闭writer,注意如果不关闭的话,那么这个空白消息是不会被传给微信服务器的
*/
response.getWriter().close();
return;
}
response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("不可识别的加密类型");
response.getWriter().close();
return;
}
/**
* 获取请求参数中所有的信息
*
* @param request
* @return
*/
public static Map<String, String> getAllRequestParam(final HttpServletRequest request) {
Map<String, String> res = new HashMap<String, String>();
Enumeration<?> temp = request.getParameterNames();
if (null != temp) {
while (temp.hasMoreElements()) {
String en = (String) temp.nextElement();
String value = request.getParameter(en);
res.put(en, value);
//logger.debug("en:"+en + ">>>>>>" + "value:" + value);
if (null == res.get(en) || "".equals(res.get(en))) {
res.remove(en);
}
}
}
return res;
}
}
4 Maven 引入 开源微信jar包,减少开发困难程度,具体请参看
<!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-mp -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>