企业应用(阿里商旅)集成 钉钉 与 微信 实现SSO单点登陆
1.钉钉准备工作
(1) 创建应用
https://open-dev.dingtalk.com/fe/app#/corp/app
(2)获取应用凭证
记录 AgentId AppKey AppSecret
(3)开通权限
开通需要的权限,并指定范围
(4)设置应用首页
构建单点登陆连接可参考 https://open.dingtalk.com/document/orgapp-server/logon-free-third-party-websites
(5)发布应用
2.微信准备工作
(1)添加应用
(2)获取应用凭证
并在我的企业中记录企业的CorpIDID
(3)设置可信域名
(4)设置工作台应用主页
此处设置的即为跳转的连接,将会携带当前授权的用户code
3.代码
(1)项目依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>Alibtrip_Sso</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Alibtrip_Sso</name> <description>Alibtrip_Sso</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>btripopen20220520</artifactId> <version>1.0.13</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>dingtalk</artifactId> <version>1.4.43</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>alibaba-dingtalk-service-sdk</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.9.3</version> </dependency> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.13</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
(2)application.properties 配置文件
# 应用名称 spring.application.name=alibtrip_sso spring.profiles.active=dev logging.level.root=INFO logging.level.org.springframework=WARN logging.level.org.spring.springboot.dao=DEBUG logging.level.com.accenture.fssc.hdl.mapper=DEBUG logging.config=classpath:logback-dev.xml logging.path=./log/alitrip # 应用服务 WEB 访问端口 server.port=9712 #阿里商旅配置 alibtrip.appKey= alibtrip.appSecret= #类型,0-自营 1-分销 alibtrip.corpTokenType= #企业代理id,值可以在开放平台中的关联企业查看企业代理id。 alibtrip.corpTokenCorpId= #钉钉配置 dingding.url= #应用id dingding.app.agentid= #应用key dingding.app.key= #应用秘钥 dingding.app.secret= #微信配置 wechat.corpid= wechat.corpsecret= wechat.getTokenUri= wechat.getUserIdUri= wechat.readUserUri=
(3)Controller 层
AlibtripController
@Slf4j @RequestMapping("/alibtrip") @Controller public class AlibtripController { private static final String URL_GET_USERINFO_BY_CODE = "https://oapi.dingtalk.com/sns/getuserinfo_bycode"; @RequestMapping("/dingding2TripCode") public void dingding2TripCode(@RequestParam("code")String code,HttpServletResponse response) { try { AlibTripService dingdingAlibTrip = (AlibTripService) SpringBeanUtils.getBean("dingdingAlibTrip"); String redirectUrl = dingdingAlibTrip.invokeAddressGet(code); response.sendRedirect(redirectUrl); } catch (Exception e) { log.error("dingding 重定向 trip出错 {}", e); } } @RequestMapping("/dingding2TripWX") public void dingding2TripWX(@RequestParam("code")String code,HttpServletResponse response) { try { AlibTripService wxAlibTrip = (AlibTripService) SpringBeanUtils.getBean("wxAlibTrip"); String redirectUrl = wxAlibTrip.invokeAddressGet(code); response.sendRedirect(redirectUrl); } catch (Exception e) { log.error("WX 重定向 trip出错 {}", e); } } }
(4)Service层
AbstractDingDing
public abstract class AbstractDingDing { public abstract String getAccessToken(String code); public abstract String getUserId(String token, String code); }
AlibTripService
public interface AlibTripService { String invokeAddressGet(String param); }
AlibTripServiceAbstract
@Slf4j @Component public abstract class AlibTripServiceAbstract implements AlibTripService{ @Autowired private ClientUtils clientUtils; @Autowired private CorpTokenUtils corpTokenUtils; public abstract String getUserId(String param); @Override public String invokeAddressGet(String param) { String empId = getUserId(param); String addressGetUrl = null; Client client = clientUtils.getClient(); String cropToken = corpTokenUtils.getToken(); AddressGetHeaders addressGetHeaders = new AddressGetHeaders(); addressGetHeaders.setXAcsBtripSoCorpToken(cropToken); AddressGetRequest addressGetRequest = new AddressGetRequest(); addressGetRequest.setUserId(empId); addressGetRequest.setActionType(4); try { AddressGetResponse addressGetResponse = client.addressGetWithOptions(addressGetRequest, addressGetHeaders, new RuntimeOptions()); AddressGetResponseBody body = addressGetResponse.body; //success的场景 addressGetUrl = body.module.getUrl(); } catch ( TeaException e) { String code = e.getCode(); String msg = e.getMessage(); Map<String, Object> data = e.getData(); //failed的场景 } catch (Exception e) { //其他异常处理 log.error("invokeAddressGet 出错 {}",e); } return addressGetUrl; } }
AlibTripServiceImpl
@Slf4j @Service public class AlibTripServiceImpl implements AlibTripService { @Autowired private ClientUtils clientUtils; @Autowired private CorpTokenUtils corpTokenUtils; @Autowired private WeChatUtil weChatUtil; @Autowired @Qualifier("oldDingDing") private AbstractDingDing abstractDingDing; public String dingding2Trip(String code) { String accessToken = abstractDingDing.getAccessToken(code); String userId = abstractDingDing.getUserId(accessToken, code); String addressGet = invokeAddressGet(userId); return addressGet; } public String dingding2TripWX(String code) { String accessToekn = weChatUtil.getAccessToekn(); String userId = weChatUtil.getUserId(accessToekn, code); String empId = weChatUtil.getEmpId(accessToekn, userId); String addressGet = invokeAddressGet(empId); return addressGet; } @Override public String invokeAddressGet(String empId) { String addressGetUrl = null; Client client = clientUtils.getClient(); String cropToken = corpTokenUtils.getToken(); AddressGetHeaders addressGetHeaders = new AddressGetHeaders(); addressGetHeaders.setXAcsBtripSoCorpToken(cropToken); AddressGetRequest addressGetRequest = new AddressGetRequest(); addressGetRequest.setUserId(empId); addressGetRequest.setActionType(4); try { AddressGetResponse addressGetResponse = client.addressGetWithOptions(addressGetRequest, addressGetHeaders, new RuntimeOptions()); AddressGetResponseBody body = addressGetResponse.body; //success的场景 addressGetUrl = body.module.getUrl(); } catch ( TeaException e) { String code = e.getCode(); String msg = e.getMessage(); Map<String, Object> data = e.getData(); //failed的场景 } catch (Exception e) { //其他异常处理 log.error("invokeAddressGet 出错 {}",e); } return addressGetUrl; } }
DingDingAlibTripService
@Service("dingdingAlibTrip") public class DingDingAlibTripService extends AlibTripServiceAbstract { @Autowired @Qualifier("oldDingDing") private AbstractDingDing abstractDingDing; @Override public String getUserId(String code) { String accessToken = abstractDingDing.getAccessToken(code); String userId = abstractDingDing.getUserId(accessToken, code); return userId; } }
WXAlibTripSevice
@Service("wxAlibTrip") public class WXAlibTripSevice extends AlibTripServiceAbstract { @Autowired private WeChatUtil weChatUtil; @Override public String getUserId(String code) { String accessToekn = weChatUtil.getAccessToekn(); String userId = weChatUtil.getUserId(accessToekn, code); String empId = weChatUtil.getEmpId(accessToekn, userId); return empId; } }
(5)工具类
AccessTokenUtils
@Slf4j @Component public class AccessTokenUtils { @Value("${alibtrip.appKey}") private String appKey; @Value("${alibtrip.appSecret}") private String appSecret; @Autowired private ClientUtils clientUtils; private AccessTokenUtils() { } ; private final String key = CacheKeyEnum.ACCESS_TOKEN_KEY.key; public String getToken() { Object ifPresent = accessTokenCache.getIfPresent(key); if (ifPresent == null) { synchronized (AccessTokenUtils.class) { if (ifPresent == null) { String accessToken = initAccessToken(); accessTokenCache.put(key, accessToken); return accessToken; } } } return (String) ifPresent; } private Cache<Object, Object> accessTokenCache = Caffeine.newBuilder().refreshAfterWrite( 7000000, TimeUnit.MILLISECONDS ).build(new CacheLoader<Object, Object>() { @Override public @Nullable Object reload(@NonNull Object key, @NonNull Object oldValue) throws Exception { String corpToken = initAccessToken(); if (corpToken == null) { return accessTokenCache.get(key, null); } return corpToken; } @Override public @Nullable Object load(Object key) throws Exception { String corpToken = initAccessToken(); if (corpToken == null) { return accessTokenCache.get(key, null); } return corpToken; } }); private String initAccessToken() { Client client = clientUtils.getClient(); try { AccessTokenRequest accessTokenCache = new AccessTokenRequest(); accessTokenCache.setAppKey(appKey); accessTokenCache.setAppSecret(appSecret); AccessTokenResponse accessTokenResponse = client.accessToken(accessTokenCache); AccessTokenResponseBody body = accessTokenResponse.body; String token = body.getData().token; return token; } catch ( TeaException e) { String code = e.getCode(); String msg = e.getMessage(); Map<String, Object> data = e.getData(); //failed的场景 StringBuffer sb = new StringBuffer(); sb.append(" code : ") .append(code) .append(" msg : ") .append(msg) .append(" data : ") .append(data); log.error(sb.toString(), e); } catch (Exception e) { //其他异常处理 log.error(LocalDateTime.now() + " initCorpToken ", e); } return null; } }
ClientUtils
@Component @Slf4j public class ClientUtils { public Client client; @Value("${alibtrip.appKey}") private String appKey; @Value("${alibtrip.appSecret}") private String appSecret; private ClientUtils() { } private void instanceClient() { Config config = new Config(); config.setAccessKeyId(appKey); config.setAccessKeySecret(appSecret); config.setProtocol("https"); config.setEndpoint("btripopen.aliyuncs.com"); try { client = new Client(config); } catch (Exception e) { e.printStackTrace(); log.error(LocalDateTime.now() + " initCorpToken ", e); } //设置签名算法 client._signatureAlgorithm = "ACS3-HMAC-SHA256"; } public Client getClient() { if (client==null){ synchronized (Object.class){ if (client==null){ instanceClient(); } } } return client; } }
CorpTokenUtils
@Slf4j @Component public class CorpTokenUtils { @Value("${alibtrip.corpTokenType}") private Integer corpTokenType; @Value("${alibtrip.corpTokenCorpId}") private String corpTokenCorpId; @Autowired private ClientUtils clientUtils; @Autowired private AccessTokenUtils accessTokenUtils; private CorpTokenUtils() { } private final String key = CacheKeyEnum.CROP_TOKEN_KEY.key; public String getToken() { Object ifPresent = corpTokenCache.getIfPresent(key); if (ifPresent == null) { synchronized (CorpTokenUtils.class) { if (ifPresent == null) { String corpToken = initCorpToken(); corpTokenCache.put(key, corpToken); return corpToken; } } } return (String) ifPresent; } private Cache<Object, Object> corpTokenCache = Caffeine.newBuilder().refreshAfterWrite( 7000000, TimeUnit.MILLISECONDS ).build(new CacheLoader<Object, Object>() { @Override public @Nullable Object reload(@NonNull Object key, @NonNull Object oldValue) throws Exception { String corpToken = initCorpToken(); if (corpToken == null) { return corpTokenCache.get(key, null); } return corpToken; } @Override public @Nullable Object load(Object key) throws Exception { String corpToken = initCorpToken(); if (corpToken == null) { return corpTokenCache.get(key, null); } return corpToken; } }); private String initCorpToken() { Client client = clientUtils.getClient(); try { CorpTokenHeaders corpTokenHeaders = new CorpTokenHeaders(); String accessTokenUtilsToken = accessTokenUtils.getToken(); corpTokenHeaders.setXAcsBtripAccessToken(accessTokenUtilsToken); CorpTokenRequest corpTokenRequest = new CorpTokenRequest(); corpTokenRequest.setType(corpTokenType); corpTokenRequest.setCorpId(corpTokenCorpId); CorpTokenResponse corpTokenResponse = client.corpTokenWithOptions(corpTokenRequest, corpTokenHeaders, new RuntimeOptions()); CorpTokenResponseBody body = corpTokenResponse.body; String token = body.getData().token; return token; } catch ( TeaException e) { String code = e.getCode(); String msg = e.getMessage(); Map<String, Object> data = e.getData(); //failed的场景 StringBuffer sb = new StringBuffer(); sb.append(" code : ") .append(code) .append(" msg : ") .append(msg) .append(" data : ") .append(data); log.error(sb.toString(), e); } catch (Exception e) { //其他异常处理 log.error(LocalDateTime.now() + " initCorpToken ", e); } return ""; } }
DingDingUtils
@Slf4j @Component("newDingDing") public class DingDingUtils extends AbstractDingDing { @Value("${dingding.url}") private String DING_URL ; @Value("${dingding.app.agentid}") private String AGENT_ID; @Value("${dingding.app.key}") private String APP_KEY; // 应用的Key @Value("${dingding.app.secret}") private String APP_SECRET ; // 应用的密码 com.aliyun.dingtalkcontact_1_0.Client client1 = null; com.aliyun.dingtalkoauth2_1_0.Client client2 = null; public static com.aliyun.dingtalkcontact_1_0.Client createClient1() throws Exception { Config config = new Config(); config.protocol = "https"; config.regionId = "oapi.dingtalk.com"; return new com.aliyun.dingtalkcontact_1_0.Client(config); } public static com.aliyun.dingtalkoauth2_1_0.Client createClient2() throws Exception { Config config = new Config(); config.protocol = "https"; config.regionId = "oapi.dingtalk.com"; return new com.aliyun.dingtalkoauth2_1_0.Client(config); } @Override public String getAccessToken(String code) { if (client2==null){ try { client2 = DingDingUtils.createClient2(); } catch (Exception e) { log.error("getAccessToken {}",e); } } GetUserTokenRequest getUserTokenRequest = new GetUserTokenRequest() .setClientId(APP_KEY) .setClientSecret(APP_SECRET) .setCode(code) .setRefreshToken(code) .setGrantType("authorization_code"); try { GetUserTokenResponse userToken = client2.getUserToken(getUserTokenRequest); return userToken.getBody().getAccessToken(); } catch (TeaException err) { if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) { // err 中含有 code 和 message 属性,可帮助开发定位问题 log.error("getAccessToken {}",err); } } catch (Exception _err) { TeaException err = new TeaException(_err.getMessage(), _err); if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) { // err 中含有 code 和 message 属性,可帮助开发定位问题 log.error("getAccessToken {}",err); } } return ""; } @Override public String getUserId(String accessToken, String code) { if (client1==null){ try { client1 = DingDingUtils.createClient1(); } catch (Exception e) { log.error("getAccessToken {}",e); } } try { GetUserHeaders headers = new GetUserHeaders(); headers.setXAcsDingtalkAccessToken(accessToken); GetUserResponse userWithOptions = client1.getUserWithOptions("me", headers, new RuntimeOptions()); GetUserResponseBody userWithOptionsBody = userWithOptions.getBody(); String unionId = userWithOptions.body.unionId; } catch (TeaException err) { if (!Common.empty(err.code) && !Common.empty(err.message)) { // err 中含有 code 和 message 属性,可帮助开发定位问题 log.error("getAccessToken {}",err); } } catch (Exception _err) { TeaException err = new TeaException(_err.getMessage(), _err); if (!Common.empty(err.code) && !Common.empty(err.message)) { // err 中含有 code 和 message 属性,可帮助开发定位问题 log.error("getAccessToken {}",err); } } return ""; } }
HttpClientUtil
@Component @Slf4j public class HttpClientUtil { CloseableHttpClient httpclient = null; CloseableHttpResponse response = null; HttpRequestRetryHandler requestRetryHandler=new HttpRequestRetryHandler() { @Override public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { if (executionCount > 3) //超过重试次数,就放弃 return false; if (exception instanceof NoHttpResponseException) {//没有响应,重试 return true; }else if (exception instanceof ConnectTimeoutException) {//连接超时,重试 return true; } else if (exception instanceof SocketTimeoutException) {//连接或读取超时,重试 return true; }else if (exception instanceof SSLHandshakeException) {//本地证书异常 return false; } else if (exception instanceof InterruptedIOException) {//被中断 return false; } else if (exception instanceof UnknownHostException) {//找不到服务器 return false; } else if (exception instanceof SSLException) {//SSL异常 return false; } else { log.info("出现异常"); } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); // 如果请求是幂等的,则重试 if (!(request instanceof HttpEntityEnclosingRequest)) return true; return false; } }; public String doGet(String url, Map<String, String> map) { String returnJson = ""; try { RequestConfig globalConfig = RequestConfig.custom() .setSocketTimeout(10000) .setConnectTimeout(10000) .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build(); httpclient = HttpClients.custom() .setRetryHandler(requestRetryHandler) .setDefaultRequestConfig(globalConfig).build(); HttpGet httpGet = new HttpGet(url); // httpGet.setProtocolVersion(HttpVersion.HTTP_1_0); // httpGet.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); // httpGet.addHeader(HTTP.CONTENT_TYPE, // "application/x-www-form-urlencoded;charset=UTF-8"); for (String key : map.keySet()) { httpGet.addHeader(key, map.get(key)); } response = httpclient.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { returnJson = "" + EntityUtils.toString(entity, "UTF-8"); } log.info(returnJson); } catch (Exception e) { log.error("连接超时",e); throw new RuntimeException(e); } finally { closeHttp(); } return returnJson; } public String doPost(String url, String data, Map<String, String> headermap, Map<String, String> bodymap) { String returnJson = ""; try { RequestConfig globalConfig = RequestConfig.custom() .setSocketTimeout(10000) .setConnectTimeout(10000) .setCookieSpec(CookieSpecs.IGNORE_COOKIES).build(); //客户端请求 httpclient = HttpClients.custom() .setRetryHandler(requestRetryHandler) .setDefaultRequestConfig(globalConfig).build(); HttpPost httpPost = new HttpPost(url); // 设置header if (bodymap != null) { for (String key : headermap.keySet()) { httpPost.addHeader(key, headermap.get(key)); } } // 设置body if (bodymap != null) { List<NameValuePair> pairs = new ArrayList<NameValuePair>(); for (Map.Entry<String, String> entry : bodymap.entrySet()) { pairs.add(new BasicNameValuePair(entry.getKey(), entry .getValue())); } httpPost.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8")); } // 参数动态传入 // StringEntity se = new StringEntity("data=" + json, "UTF-8"); if (data != null && !data.equals("")) { StringEntity se = new StringEntity(data, "UTF-8"); se.setContentEncoding("UTF-8"); se.setContentType("application/json");// 发送json需要设置contentType httpPost.setEntity(se); } response = httpclient.execute(httpPost); // 解析返结果 HttpEntity entity = response.getEntity(); if (entity != null) { returnJson = "" + EntityUtils.toString(entity, "UTF-8"); } } catch (Exception e) { log.error("连接超时",e); throw new RuntimeException(e); } finally { closeHttp(); } return returnJson; } public void closeHttp() { try { if (httpclient != null) { httpclient.close(); } if (response != null) { response.close(); } } catch (Exception e) { e.printStackTrace(); } } }
OldDingDingUtis
@Slf4j @Component("oldDingDing") public class OldDingDingUtis extends AbstractDingDing { @Value("${dingding.url}") private String DING_URL ; @Value("${dingding.app.agentid}") private String AGENT_ID; @Value("${dingding.app.key}") private String APP_KEY; // 应用的Key @Value("${dingding.app.secret}") private String APP_SECRET ; // 应用的密码 // 获取钉钉token public String getAccessToken() { String result = null; DefaultDingTalkClient client = new DefaultDingTalkClient(DING_URL + "/gettoken"); OapiGettokenRequest request = new OapiGettokenRequest(); request.setAppkey(APP_KEY); request.setAppsecret(APP_SECRET); request.setHttpMethod("GET"); try { OapiGettokenResponse response = client.execute(request); result = response.isSuccess() ? response.getAccessToken() : null; } catch (ApiException e) { log.error("获取钉钉AccessToken错误 {}" , e); } return result; } @Override public String getAccessToken(String code) { return getAccessToken(); } @Override public String getUserId(String token, String code) { OapiV2UserGetResponse rspGetResponse = null; try { // 通过临时授权码获取授权用户的个人信息 DefaultDingTalkClient client2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode"); OapiSnsGetuserinfoBycodeRequest reqBycodeRequest = new OapiSnsGetuserinfoBycodeRequest(); reqBycodeRequest.setTmpAuthCode(code); OapiSnsGetuserinfoBycodeResponse bycodeResponse = client2.execute(reqBycodeRequest, APP_KEY, APP_SECRET); // 根据unionid获取userid String unionid = bycodeResponse.getUserInfo().getUnionid(); DingTalkClient clientDingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid"); OapiUserGetbyunionidRequest reqGetbyunionidRequest = new OapiUserGetbyunionidRequest(); reqGetbyunionidRequest.setUnionid(unionid); OapiUserGetbyunionidResponse oapiUserGetbyunionidResponse = clientDingTalkClient.execute(reqGetbyunionidRequest, token); // 根据userId获取用户信息 String userid = oapiUserGetbyunionidResponse.getResult().getUserid(); DingTalkClient clientDingTalkClient2 = new DefaultDingTalkClient( "https://oapi.dingtalk.com/topapi/v2/user/get"); OapiV2UserGetRequest reqGetRequest = new OapiV2UserGetRequest(); reqGetRequest.setUserid(userid); reqGetRequest.setLanguage("zh_CN"); rspGetResponse = clientDingTalkClient2.execute(reqGetRequest, token); return rspGetResponse.getResult().getJobNumber(); } catch (ApiException e) { e.printStackTrace(); } return ""; } }
SpringBeanUtils
@Component public class SpringBeanUtils implements ApplicationContextAware { private static ApplicationContext app; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (app == null) { app = applicationContext; } } // 获得applicationContext public static ApplicationContext getApplicationContext() throws Exception { return app; } // 通过class获取Bean public static <T> T getBean(Class<T> clazz) throws Exception { return getApplicationContext().getBean(clazz); } // 通过name获取 Bean public static Object getBean(String name) throws Exception { return getApplicationContext().getBean(name); } }
WeChatUtil
@Slf4j @Component public class WeChatUtil { @Autowired private HttpClientUtil httpClientUtil; @Value("${wechat.corpid}") private String corpid; @Value("${wechat.corpsecret}") private String corpsecret; @Value("${wechat.getTokenUri}") private String wxgetTokenUri; @Value("${wechat.getUserIdUri}") private String wxgetUserIdUri; @Value("${wechat.readUserUri}") private String wxreadUserUri; private static Long tokenTime = 0L; //2小时过期 private final Integer invalidTime = 2; private String accesstToken; //获取登陆凭证 public String getAccessToekn() { if (System.currentTimeMillis() - tokenTime > invalidTime * 1000 * 60) { tokenTime = System.currentTimeMillis(); String url = wxgetTokenUri + "?corpid=" + corpid + "&corpsecret=" + corpsecret; String doGet = httpClientUtil.doGet(url, new HashMap<>()); HashMap map = JSON.parseObject(doGet, HashMap.class); if ("ok".equals(map.get("errmsg"))) { accesstToken = (String) map.get("access_token"); return accesstToken; } else { log.error("getAccessToekn 出错 {}",map.get("errmsg")); return ""; } } else { return accesstToken; } } //获取访问用户ID public String getUserId(String accessToken, String code) { String url = wxgetUserIdUri + "?access_token=" + accessToken + "&code=" + code; String doGet = httpClientUtil.doGet(url, new HashMap<>()); HashMap map = JSON.parseObject(doGet, HashMap.class); if ("ok".equals(map.get("errmsg"))) { return (String) map.get("UserId"); } else { throw new RuntimeException(map.get("errcode")+" "+(String) map.get("errmsg")); } } public String getEmpId(String accessToken,String userId){ String url = wxreadUserUri + "?access_token=" + accessToken + "&userid=" + userId; String doGet = httpClientUtil.doGet(url, new HashMap<>()); HashMap map = JSON.parseObject(doGet, HashMap.class); JSONObject jsonDoget = (JSONObject) JSONObject.parseObject(JSON.parseObject(doGet).getString("extattr")).getJSONArray("attrs").get(0); String empId = (String) jsonDoget.get("value"); if ("ok".equals(map.get("errmsg"))) { return empId; } else { throw new RuntimeException(map.get("errcode")+" "+(String) map.get("errmsg")); } } }
(6) 枚举类
CacheKeyEnum
public enum CacheKeyEnum { ACCESS_TOKEN_KEY("accessToken"), CROP_TOKEN_KEY("corpToken") ; public String key; CacheKeyEnum(String key) { this.key = key; } public String getkey() { return key; } public void setkey(String key) { this.key = key; } @Override public String toString() { return super.toString(); } }#java#