mirror of
https://gitee.com/wangkang/udf.git
synced 2026-10-29 05:25:13 +00:00
添加微信MP的集成
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -20,4 +20,9 @@ public class WeixinMpApiProperties {
|
||||
*/
|
||||
private Map<String, WeixinMpApiAuthMeta> auth;
|
||||
|
||||
/**
|
||||
* sns接口地址
|
||||
*/
|
||||
private Map<String, String> snsPath;
|
||||
|
||||
}
|
||||
|
||||
+22
-1
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 描述 : 获得节点值
|
||||
*
|
||||
+1
-1
@@ -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>
|
||||
+32
@@ -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;
|
||||
|
||||
}
|
||||
+51
@@ -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;
|
||||
|
||||
}
|
||||
+77
@@ -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;
|
||||
|
||||
}
|
||||
+2
-3
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user