添加微信MP的集成

This commit is contained in:
udf_admin@163.com
2018-01-29 23:31:07 +08:00
parent 418b113e1f
commit 9957cd70a4
8 changed files with 332 additions and 5 deletions
@@ -0,0 +1,142 @@
package org.itkk.udf.weixin.mp.api;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.itkk.udf.weixin.mp.api.domain.BaseResult;
import org.itkk.udf.weixin.mp.api.domain.Oauth2Token;
import org.itkk.udf.weixin.mp.api.domain.Oauth2UserInfo;
import org.itkk.udf.weixin.mp.api.meta.WeixinMpApiAuthMeta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
/**
* Oauth2
*/
@Component
public class Oauth2 {
/**
* weixinMpApiProperties
*/
@Autowired
private WeixinMpApiProperties weixinMpApiProperties;
/**
* externalRestTemplate
*/
@Autowired
@Qualifier("externalRestTemplate")
private RestTemplate externalRestTemplate;
/**
* objectMapper
*/
@Autowired
private ObjectMapper objectMapper;
/**
* 通过code换取网页授权access_token
*
* @param businessCode 业务代码(关联appid等信息)
* @param code 填写第一步获取的code参数
* @return Oauth2Token
* @throws IOException IOException
*/
public Oauth2Token accessToken(String businessCode, String code) throws IOException {
//获得认证相关信息
WeixinMpApiAuthMeta auth = weixinMpApiProperties.getAuth().get(businessCode);
//获得接口地址
String path = weixinMpApiProperties.getSnsPath().get("sns_oauth2_access_token");
//拼接url
StringBuilder url = new StringBuilder(path);
url.append("?appid=").append(auth.getAppId()).append("&secret=").append(auth.getAppSecret()).append("&code=").append(code).append("&grant_type=authorization_code");
//请求
ResponseEntity<String> result = externalRestTemplate.getForEntity(url.toString(), String.class);
//解析结果
Oauth2Token token = objectMapper.readValue(result.getBody(), Oauth2Token.class);
//验证
WeixinMpConsont.checkResult(token);
//返回
return token;
}
/**
* 刷新access_token(如果需要)
*
* @param businessCode 业务代码(关联appid等信息)
* @param refreshToken 填写为refresh_token
* @return Oauth2Token
* @throws IOException IOException
*/
public Oauth2Token refreshToken(String businessCode, String refreshToken) throws IOException {
//获得认证相关信息
WeixinMpApiAuthMeta auth = weixinMpApiProperties.getAuth().get(businessCode);
//获得接口地址
String path = weixinMpApiProperties.getSnsPath().get("sns_oauth2_refresh_token");
//拼接url
StringBuilder url = new StringBuilder(path);
url.append("?appid=").append(auth.getAppId()).append("&refresh_token=").append(refreshToken).append("&grant_type=refresh_token");
//请求
ResponseEntity<String> result = externalRestTemplate.getForEntity(url.toString(), String.class);
//解析结果
Oauth2Token token = objectMapper.readValue(result.getBody(), Oauth2Token.class);
//验证
WeixinMpConsont.checkResult(token);
//返回
return token;
}
/**
* 拉取用户信息(需scope为 snsapi_userinfo)
*
* @param accessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
* @param openId 用户的唯一标识
* @param lang 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
* @return Oauth2UserInfo
* @throws IOException IOException
*/
public Oauth2UserInfo userInfo(String accessToken, String openId, String lang) throws IOException {
//获得接口地址
String path = weixinMpApiProperties.getSnsPath().get("sns_userinfo");
//拼接url
StringBuilder url = new StringBuilder(path);
url.append("?access_token=").append(accessToken).append("&openid=").append(openId).append("&lang=").append(lang);
//请求
ResponseEntity<String> result = externalRestTemplate.getForEntity(url.toString(), String.class);
//解析结果
Oauth2UserInfo oauth2UserInfo = objectMapper.readValue(result.getBody(), Oauth2UserInfo.class);
//验证
WeixinMpConsont.checkResult(oauth2UserInfo);
//返回
return oauth2UserInfo;
}
/**
* 检验授权凭证(access_token)是否有效
*
* @param accessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
* @param openId 用户的唯一标识
* @return BaseResult
* @throws IOException IOException
*/
public BaseResult auth(String accessToken, String openId) throws IOException {
//获得接口地址
String path = weixinMpApiProperties.getSnsPath().get("sns_auth");
//拼接url
StringBuilder url = new StringBuilder(path);
url.append("?access_token=").append(accessToken).append("&openid=").append(openId);
//请求
ResponseEntity<String> result = externalRestTemplate.getForEntity(url.toString(), String.class);
//解析结果
BaseResult baseResult = objectMapper.readValue(result.getBody(), BaseResult.class);
//验证
WeixinMpConsont.checkResult(baseResult);
//返回
return baseResult;
}
}
@@ -20,4 +20,9 @@ public class WeixinMpApiProperties {
*/
private Map<String, WeixinMpApiAuthMeta> auth;
/**
* sns接口地址
*/
private Map<String, String> snsPath;
}
@@ -1,5 +1,6 @@
package org.itkk.udf.weixin.mp;
package org.itkk.udf.weixin.mp.api;
import org.itkk.udf.weixin.mp.api.domain.BaseResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
@@ -24,6 +25,26 @@ public class WeixinMpConsont {
}
/**
* <p>
* 检查返回值
* </p>
*
* @param br 返回值
*/
public static void checkResult(BaseResult br) {
//判断是否拿到返回值
if (br == null) {
//返回异常信息
throw new WeixinMpException("error");
}
//是否有错误(0为正常处理)
if (br.getErrcode() != null && !"0".equals(br.getErrcode())) {
//返回异常信息
throw new WeixinMpException(br.getErrcode() + ":" + br.getErrmsg());
}
}
/**
* 描述 : 获得节点值
*
@@ -4,7 +4,7 @@
* Created by wangkang
* Copyright (C) 2016 itkk.org, All rights reserved.
*/
package org.itkk.udf.weixin.mp;
package org.itkk.udf.weixin.mp.api;
/**
* <p>
@@ -0,0 +1,32 @@
package org.itkk.udf.weixin.mp.api.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* BaseResult
*/
@Data
@ApiModel(description = "微信基础返回信息")
public class BaseResult implements Serializable {
/**
* ID
*/
private static final long serialVersionUID = 1L;
/**
* errcode
*/
@ApiModelProperty(value = "错误代码", required = true, dataType = "string")
private String errcode;
/**
* errmsg
*/
@ApiModelProperty(value = "错误描述", required = true, dataType = "string")
private String errmsg;
}
@@ -0,0 +1,51 @@
package org.itkk.udf.weixin.mp.api.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* Oauth2Token
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(description = "网页授权token信息")
public class Oauth2Token extends BaseResult {
/**
* ID
*/
private static final long serialVersionUID = 1L;
/**
* access_token
*/
@ApiModelProperty(value = "网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同", required = true, dataType = "string")
private String access_token; //NOSONAR
/**
* expires_in
*/
@ApiModelProperty(value = "ccess_token接口调用凭证超时时间,单位(秒)", required = true, dataType = "int")
private Integer expires_in; //NOSONAR
/**
* refresh_token
*/
@ApiModelProperty(value = "用户刷新access_token", required = true, dataType = "string")
private String refresh_token; //NOSONAR
/**
* openid
*/
@ApiModelProperty(value = "用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID", required = true, dataType = "string")
private String openid;
/**
* scope
*/
@ApiModelProperty(value = "用户授权的作用域,使用逗号(,)分隔", required = true, dataType = "string")
private String scope;
}
@@ -0,0 +1,77 @@
package org.itkk.udf.weixin.mp.api.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
* Oauth2Token
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(description = "网页授权用户信息")
public class Oauth2UserInfo extends BaseResult {
/**
* ID
*/
private static final long serialVersionUID = 1L;
/**
* openid
*/
@ApiModelProperty(value = "用户的唯一标识", required = true, dataType = "string")
private String openid;
/**
* nickname
*/
@ApiModelProperty(value = "用户昵称", required = true, dataType = "string")
private String nickname;
/**
* sex
*/
@ApiModelProperty(value = "用户的性别,值为1时是男性,值为2时是女性,值为0时是未知", required = true, dataType = "string")
private String sex;
/**
* province
*/
@ApiModelProperty(value = "用户个人资料填写的省份", required = true, dataType = "string")
private String province;
/**
* city
*/
@ApiModelProperty(value = "普通用户个人资料填写的城市", required = true, dataType = "string")
private String city;
/**
* country
*/
@ApiModelProperty(value = " 国家,如中国为CN", required = true, dataType = "string")
private String country;
/**
* headimgurl
*/
@ApiModelProperty(value = "用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。", required = true, dataType = "string")
private String headimgurl;
/**
* privilege
*/
@ApiModelProperty(value = "用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)", required = true, dataType = "array")
private List<String> privilege;
/**
* unionid
*/
@ApiModelProperty(value = "只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。", required = true, dataType = "string")
private String unionid;
}
@@ -4,8 +4,8 @@ import com.qq.weixin.mp.aes.WXBizMsgCrypt;
import lombok.extern.slf4j.Slf4j;
import org.itkk.udf.amqp.rabbitmq.Rabbitmq;
import org.itkk.udf.amqp.rabbitmq.RabbitmqMessage;
import org.itkk.udf.weixin.mp.WeixinMpConsont;
import org.itkk.udf.weixin.mp.WeixinMpException;
import org.itkk.udf.weixin.mp.api.WeixinMpConsont;
import org.itkk.udf.weixin.mp.api.WeixinMpException;
import org.itkk.udf.weixin.mp.api.ShaOne;
import org.itkk.udf.weixin.mp.api.WeixinMpApiConfig;
import org.itkk.udf.weixin.mp.api.WeixinMpApiProperties;
@@ -73,7 +73,6 @@ public class WeixinMpCallbackService {
* @param timestamp timestamp
* @param nonce nonce
* @param inputMessage inputMessage
* @return String
* @throws Exception Exception
*/
@Async