微信
WechatConfig.java
package com.meeno.chemical.common.sdk.wechat.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @description: 微信Config
* @author: Wzq
* @create: 2020-08-10 14:28
*/
@Component
public class WechatConfig {
/**
* 微信appid
*/
public static String appId;
/**
* 微信secret
*/
public static String secret;
/**
* 网站重定向地址
*/
public static String redirectUri;
@Value("${wechat.app-id}")
public void setAppId(String appId){
WechatConfig.appId = appId;
}
@Value("${wechat.app-secret}")
public void setSecret(String secret){
WechatConfig.secret = secret;
}
@Value("${wechat.redirect-uri}")
public void setRedirectUri(String redirectUri){
WechatConfig.redirectUri = redirectUri;
}
}
WechatAccessToken.java
package com.meeno.chemical.common.sdk.wechat.result;
import lombok.*;
/**
* @description: 微信返回AccessToken
* @author: Wzq
* @create: 2020-08-14 14:14
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class WechatAccessToken {
/**
* 接口调用凭证
*/
private String access_token;
/**
* access_token接口调用凭证超时时间,单位(秒)
*/
private String expires_in;
/**
* 用户刷新access_token
*/
private String refresh_token;
/**
* 授权用户唯一标识
*/
private String openid;
/**
* 用户授权的作用域,使用逗号(,)分隔
*/
private String scope;
/**
* 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。
*/
private String unionid;
}
WechatApi.java
package com.meeno.chemical.common.sdk.wechat;
import com.alibaba.fastjson.JSONObject;
import com.meeno.chemical.common.http.client.OkHttpUtils;
import com.meeno.chemical.common.sdk.wechat.config.WechatConfig;
import com.meeno.chemical.common.sdk.wechat.result.WechatAccessToken;
import com.meenoframework.util.MeenoAssert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import static org.apache.logging.log4j.ThreadContext.containsKey;
/**
* @description: 微信Api
* @author: Wzq
* @create: 2020-08-10 14:28
*/
@Slf4j
public class WechatApi {
/**
* 获取网站微信登录跳转地址
* @param state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
* @return
*/
public static String getLoginUrl(String state){
StringBuffer url = new StringBuffer();
url.append("https://open.weixin.qq.com/connect/qrconnect?");
url.append("appid=%s&");
url.append("redirect_uri=%s&");
url.append("response_type=%s&");
url.append("scope=%s&");
url.append("state=%s");
String appId = WechatConfig.appId;
String redirectUri = WechatConfig.redirectUri;
String responseType = "code";
String scope = "snsapi_login";
String loginUrlStr = String.format(url.toString() , appId, redirectUri, responseType, scope, state);
return loginUrlStr;
}
/**
* 获取授权token
* @param code 通过 getLoginUrl 获取的code
* @return
*/
public static WechatAccessToken getAccessToken(String code){
StringBuffer url = new StringBuffer();
url.append("https://api.weixin.qq.com/sns/oauth2/access_token?");
url.append("appid=%s&");
url.append("secret=%s&");
url.append("code=%s&");
url.append("grant_type=%s");
String appId = WechatConfig.appId;
String secret = WechatConfig.secret;
String grantType = "authorization_code";
String urlStr = String.format(url.toString(), appId, secret, code, grantType);
String resultStr = OkHttpUtils.get(urlStr);
log.info("getAccessToken---" + resultStr);
JSONObject resultJson = JSONObject.parseObject(resultStr);
boolean hasOpenid = resultJson.containsKey("openid");
MeenoAssert.isTrue(hasOpenid, "wechat get accessToken err!");
WechatAccessToken wechatAccessToken = JSONObject.parseObject(resultStr,WechatAccessToken.class);
return wechatAccessToken;
}
/**
* 获取用户信息
* @param accessToken
* @param openId
* @return
*/
public static JSONObject getUserInfo(String accessToken,String openId){
StringBuffer url = new StringBuffer();
url.append("https://api.weixin.qq.com/sns/userinfo?");
url.append("access_token=%s&");
url.append("openid=%s&");
url.append("lang=%s");
String lang = "zh-CN";
String urlStr = String.format(url.toString(), accessToken, openId, lang);
String resultStr = OkHttpUtils.get(urlStr);
JSONObject jsonObject = JSONObject.parseObject(resultStr);
boolean hasErrCode = jsonObject.containsKey("errcode");
MeenoAssert.isTrue(!hasErrCode, "wechat get userInfo err!");
return jsonObject;
}
}
微博
WeiBoConfig.java
package com.meeno.chemical.common.sdk.weibo.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @description: 微博配置类
* @author: Wzq
* @create: 2020-05-29 15:36
*/
@Configuration
@ConfigurationProperties(prefix = "weibo")
@Setter
@Getter
public class WeiBoConfig {
/**
* AppId
*/
private String appId;
/**
* App Secret
*/
private String appSecret;
/**
* 回调地址
*/
private String redirectUri;
}
WbTokenBody.java
package com.meeno.chemical.common.sdk.weibo.entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* @description: 微博token返回实体
* @author: Wzq
* @create: 2020-05-29 16:08
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class WbTokenBody {
/**
* access_token
*/
private String access_token;
/**
* remind_in
*/
private String remind_in;
/**
* expires_in
*/
private Long expires_in;
/**
* uid 微博用户id
*/
private String uid;
/**
* isRealName
*/
private String isRealName;
}
WbUserInfo.java
package com.meeno.chemical.common.sdk.weibo.entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* @description: 微博UserInfo
* https://open.weibo.com/wiki/2/users/show
* @author: Wzq
* @create: 2020-05-29 16:42
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class WbUserInfo {
/**
* 用户UID
*/
private Long id;
/**
* 字符串型的用户UID
*/
private String idstr;
/**
* 用户昵称
*/
private String screen_name;
/**
* 友好显示名称
*/
private String name;
/**
* 用户所在省级ID
*/
private Integer province;
/**
* 用户所在城市ID
*/
private Integer city;
/**
* 用户所在地
*/
private String location;
/**
* 用户个人描述
*/
private String description;
/**
* 用户博客地址
*/
private String url;
/**
* 用户头像地址(中图),50×50像素
*/
private String profile_image_url;
/**
* 用户的微博统一URL地址
*/
private String profile_url;
/**
* 用户的个性化域名
*/
private String domain;
/**
* 用户的微号
*/
private String weihao;
/**
* 性别,m:男、f:女、n:未知
*/
private String gender;
/**
* 用户创建(注册)时间
*/
private String created_at;
/**
* 用户头像地址(大图),180×180像素
*/
private String avatar_large;
/**
* 用户头像地址(高清),高清头像原图
*/
private String avatar_hd;
}
WeiBoClient.java
package com.meeno.chemical.common.sdk.weibo.login;
import com.alibaba.fastjson.JSONObject;
import com.meeno.chemical.common.sdk.weibo.config.WeiBoConfig;
import com.meeno.chemical.common.sdk.weibo.entity.WbTokenBody;
import com.meeno.chemical.common.sdk.weibo.entity.WbUserInfo;
import com.meenoframework.util.MeenoAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @description: 微博客户端
* @author: Wzq
* @create: 2020-05-29 16:48
*/
@Component
public class WeiBoClient {
@Autowired
private WeiBoConfig weiBoConfig;
/**
* 获取授权地址 在网页输入此地址就能到微博授权页面
* @return
*/
public String getAuthUrl(){
String authUrl = WeiBoLoginUtils.getAuthUrl(weiBoConfig.getAppId(), weiBoConfig.getRedirectUri());
return authUrl;
}
/**
* 获取token
* @param code
* @return
*/
public WbTokenBody getAccessToken(String code){
String accessTokenJson = WeiBoLoginUtils.getAccessToken(weiBoConfig.getAppId(), weiBoConfig.getAppSecret(), weiBoConfig.getRedirectUri(), code);
WbTokenBody wbTokenBody = JSONObject.parseObject(accessTokenJson, WbTokenBody.class);
String access_token = wbTokenBody.getAccess_token();
MeenoAssert.hasLength(access_token,"access_token is empty!");
return wbTokenBody;
}
/**
* 获取微博用户信息
* @param tokenBody
* @return
*/
public WbUserInfo getUserInfo(WbTokenBody tokenBody){
String userInfoJson = WeiBoLoginUtils.getUserInfo(tokenBody.getAccess_token(), tokenBody.getUid());
WbUserInfo wbUserInfo = JSONObject.parseObject(userInfoJson, WbUserInfo.class);
String idstr = wbUserInfo.getIdstr();
MeenoAssert.hasLength(idstr,"userInfo not found!");
return wbUserInfo;
}
/**
* 获取微博用户信息
* @param accessToken
* @param uid
* @return
*/
public WbUserInfo getUserInfo(String accessToken,String uid){
String userInfoJson = WeiBoLoginUtils.getUserInfo(accessToken, uid);
WbUserInfo wbUserInfo = JSONObject.parseObject(userInfoJson, WbUserInfo.class);
String idstr = wbUserInfo.getIdstr();
MeenoAssert.hasLength(idstr,"userInfo not found!");
return wbUserInfo;
}
}
WeiBoLoginUtils.java
package com.meeno.chemical.common.sdk.weibo.login;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.meeno.chemical.common.http.client.OkHttpUtils;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/**
* @description: 微博登录Utils
* https://open.weibo.com/wiki/Connect/login
* @author: Wzq
* @create: 2020-05-29 15:36
*/
@Slf4j
public class WeiBoLoginUtils {
/**
* 获取授权地址 在网页输入此地址就能到微博授权页面
* @param clientId appId
* @param redirectUri 授权回调地址,需要与配置的回调地址一致
* @return
*/
public static String getAuthUrl(String clientId,String redirectUri){
//https://open.weibo.com/wiki/Oauth2/authorize
//OAuth2的authorize接口
String url = "https://api.weibo.com/oauth2/authorize?client_id="+clientId + "&response_type=code&redirect_uri=" + redirectUri;
return url;
}
/**
* 获取授权Token
* @param clientId AppId
* @param clientSecret appSecret
* @param redirectUri 授权回调地址,需要与配置的回调地址一致
* @param code 网页授权成功返回的code
* @return
*/
public static String getAccessToken(String clientId,String clientSecret,String redirectUri,String code){
//OAuth2的access_token接口
//https://open.weibo.com/wiki/Oauth2/access_token
String url = "https://api.weibo.com/oauth2/access_token";
Map<String,String> params = Maps.newHashMap();
params.put("client_id",clientId);
params.put("client_secret",clientSecret);
params.put("grant_type","authorization_code");
params.put("redirect_uri",redirectUri);
params.put("code",code);
String str = OkHttpUtils.post(url, params);
log.info(str);
return str;
}
/**
* 获取用户信息
* @param accessToken 授权token
* @param uid 微信用户uid
* @return
*/
public static String getUserInfo(String accessToken,String uid){
//根据用户ID获取用户信息
//https://open.weibo.com/wiki/2/users/show
String url = "https://api.weibo.com/2/users/show.json";
Map<String,String> params = Maps.newHashMap();
params.put("access_token",accessToken);
params.put("uid",uid);
String str = OkHttpUtils.get(url, params);
log.info(str);
return str;
}
public static void main(String[] args) {
/* String code = "5f42798681b00c14688ffe8dece401ae";
String accessTokenJson = getAccessToken("283928844", "96d1d6081a8c0c133fd0ee71c05f1288", "www.meeno.net", code);
log.info(accessTokenJson);
JSONObject jsonObject = JSONObject.parseObject(accessTokenJson);
String access_token = jsonObject.getString("access_token");
String uid = jsonObject.getString("uid");
String userInfo = getUserInfo(access_token, uid);
log.info(userInfo);*/
String authUrl = getAuthUrl("283928844", "www.meeno.net");
log.info(authUrl);
}
}
QQConfig.java
package com.meeno.chemical.common.sdk.qq.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @description: qqconfig
* @author: Wzq
* @create: 2020-08-17 16:28
*/
@Component
public class QQConfig {
/**
* 应用的appid
*/
public static String appId;
/**
* app-key
*/
public static String appKey;
/**
* 成功授权后的回调地址
*/
public static String redirectUri;
@Value("${qq.app-id}")
public void setAppId(String appId){
QQConfig.appId = appId;
}
@Value("${qq.app-key}")
public void setAppKey(String appKey){
QQConfig.appKey = appKey;
}
@Value("${qq.redirect-uri}")
public void setRedirectUri(String redirectUri){
QQConfig.redirectUri = redirectUri;
}
}
QQApi.java
package com.meeno.chemical.common.sdk.qq;
import com.alibaba.fastjson.JSONObject;
import com.meeno.chemical.common.http.client.OkHttpUtils;
import com.meeno.chemical.common.sdk.qq.config.QQConfig;
import com.meenoframework.util.MeenoAssert;
import lombok.extern.slf4j.Slf4j;
/**
* @description: qqApi
* @author: Wzq
* @create: 2020-08-17 14:15
*/
@Slf4j
public class QQApi {
/**
* 获取qq登录地址
* @param state 业务的标识 sessionId
* @return
*/
public static String getLoginUrl(String state){
StringBuffer url = new StringBuffer();
url.append("https://graph.qq.com/oauth2.0/authorize?");
url.append("response_type=%s&");
url.append("client_id=%s&");
url.append("redirect_uri=%s&");
url.append("state=%s&");
String responseType = "code";
String appId = QQConfig.appId;
String redirectUri = QQConfig.redirectUri;
String loginUrlStr = String.format(url.toString() , responseType, appId, redirectUri, state);
return loginUrlStr;
}
/**
* 通过Authorization Code获取Access Token
* @param code
* @return
*/
public static String getAccessToken(String code){
StringBuffer url = new StringBuffer();
url.append("https://graph.qq.com/oauth2.0/token?");
url.append("grant_type=%s&");
url.append("client_id=%s&");
url.append("client_secret=%s&");
url.append("code=%s&");
url.append("redirect_uri=%s&");
url.append("fmt=%s");
String grantType = "authorization_code";
String clientId = QQConfig.appId;
String clientSecret = QQConfig.appKey;
String redirectUri = QQConfig.redirectUri;
String fmt = "json";
String urlStr = String.format(url.toString(), grantType, clientId, clientSecret, code, redirectUri, fmt);
String resultStr = OkHttpUtils.get(urlStr);
log.info("getAccessToken---" + resultStr);
JSONObject resultJson = JSONObject.parseObject(resultStr);
return resultJson.getString("access_token");
}
/**
* 获取用户信息
* @param accessToken
* @return
*/
public static String getOpenId(String accessToken){
StringBuffer url = new StringBuffer();
url.append("https://graph.qq.com/oauth2.0/me?");
url.append("access_token=%s&");
url.append("fmt=%s");
String fmt = "json";
String urlStr = String.format(url.toString(), accessToken, fmt);
String resultStr = OkHttpUtils.get(urlStr);
log.info("getOpenId---" + resultStr);
JSONObject resultJson = JSONObject.parseObject(resultStr);
String openid = resultJson.getString("openid");
MeenoAssert.hasLength(openid,"get openid error!");
return openid;
}
}
工具类
OkHttpUtils.java
package com.meeno.chemical.common.http.client;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okio.BufferedSink;
import okio.Okio;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
/**
* @description: OkHttp请求
* @author: Wzq
* @create: 2020-05-29 12:20
*/
@Slf4j
public class OkHttpUtils {
/**
* Get请求
* @param url URL地址
* @return 返回结果
*/
public static String get(String url,Map<String,String> params){
String result=null;
try {
HttpUrl.Builder httpBuilder = HttpUrl.parse(url).newBuilder();
if (params != null) {
for(Map.Entry<String, String> param : params.entrySet()) {
httpBuilder.addQueryParameter(param.getKey(),param.getValue());
}
}
OkHttpClient okHttpClient=new OkHttpClient();
Request request = new Request.Builder().url(httpBuilder.build()).build();
Response response = okHttpClient.newCall(request).execute();
result=response.body().string();
log.info("Get请求返回:{}",result);
return result;
}catch (Exception e){
log.error("OkHttp[Get]请求异常",e);
return result;
}
}
public static String get(String url){
String str = OkHttpUtils.get(url, null);
return str;
}
/**
* Post请求
* @param url URL地址
* @param params 参数
* @return 返回结果
*/
public static String post(String url, Map<String,String> params){
String result=null;
if (params==null){
params=new HashMap<String, String>();
}
try {
OkHttpClient okHttpClient=new OkHttpClient();
FormBody.Builder formBodyBuilder = new FormBody.Builder();
//添加参数
log.info("params:{}", JSON.toJSONString(params));
for (Map.Entry<String,String> map:params.entrySet()){
String key=map.getKey();
String value;
if (map.getValue()==null){
value="";
}else{
value=map.getValue();
}
formBodyBuilder.add(key,value);
}
FormBody formBody =formBodyBuilder.build();
Request request = new Request.Builder().url(url).post(formBody).build();
Response response = okHttpClient.newCall(request).execute();
result=response.body().string();
log.info("Post请求返回:{}",result);
return result;
}catch (Exception e){
log.error("OkHttp[Post]请求异常",e);
return result;
}
}
/**
* 上传文件请求(Post请求)
* @param url URL地址
* @param params 文件 key:参数名 value:文件 (可以多文件)
* @return 返回结果
*/
public static String upload(String url, Map<String, File> params){
String result=null;
try {
OkHttpClient okHttpClient=new OkHttpClient();
MultipartBody.Builder multipartBodyBuilder =new MultipartBody.Builder().setType(MultipartBody.FORM);
for (Map.Entry<String,File> map:params.entrySet()){
String key=map.getKey();
File file=map.getValue();
if (file==null||(file.exists() && file.length() == 0)){
continue;
}
multipartBodyBuilder.addFormDataPart(key,file.getName(),RequestBody.create(MediaType.parse("multipart/form-data"), file));
}
RequestBody requestBody =multipartBodyBuilder.build();
Request request = new Request.Builder().url(url).post(requestBody).build();
Response response = okHttpClient.newCall(request).execute();
result=response.body().string();
log.info("Upload请求返回:{}",result);
return result;
}catch (Exception e){
log.error("OkHttp[Upload]请求异常",e);
return result;
}
}
/**
* 下载文件请求(Get请求)
* @param url URL地址
* @param savePath 保存路径(包括文件名)
* @return 文件保存路径
*/
public static String download(String url,String savePath){
String result=null;
try {
OkHttpClient okHttpClient=new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = okHttpClient.newCall(request).execute();
File file=new File(savePath);
if (!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
BufferedSink sink = Okio.buffer((Okio.sink(file)));
sink.writeAll(response.body().source());
sink.flush();
sink.close();
result=savePath;
log.info("Download请求返回:{}",result);
return result;
}catch (Exception e){
log.error("OkHttp[Download]请求异常",e);
return result;
}
}
}
pom.xml
<!--okhttp-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.6.0</version>
</dependency>