package cn.com.goldenwater.dcproj.utils.http; import cn.com.goldenwater.dcproj.utils.HttpHeadHelper; import cn.com.goldenwater.id.util.UuidUtil; import com.dcxx.framework.watermanagesdk.model.ResponseMessage; import com.dcxx.framework.watermanagesdk.utils.EncryptHelper; import com.dcxx.framework.watermanagesdk.utils.JsonHelper; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; @Component public class SsoHttpHelper { private Logger logger = LoggerFactory.getLogger(getClass()); // 定义接口常量 public static String GET_ACCESS_TOKEN = "/service/v1/token/getAccessToken";//获取access_token @Value("${watermanage.baseurl}") private String baseurl; @Value("${watermanage.appkey}") private String appkey; @Value("${watermanage.appsecret}") private String appsecret; @Autowired private RedisTemplate redisTemplate; /** * @Description * @date 2020-07-15 * 接入资源业务系统 * 获取access_token保存至redis中,设置有效时长7200秒, */ public String getAccessToken() throws Exception { // 获取waterManageAccessToken,如果为空,则请求waterManageAccessToken,保存至redis,时长为7300秒,过期后需重新生成放入 String waterManageAccessToken = (String) redisTemplate.opsForValue().get("watermanage_access_token"); logger.info("watermanage_access_token是否为空:" + waterManageAccessToken); if (StringUtils.isBlank(waterManageAccessToken)) { Map parameter = new HashMap<>();//添加参数 parameter.put("appkey", appkey); String nonce = UuidUtil.genernateNonce(8); parameter.put("nonce", nonce); String timestamp = System.currentTimeMillis() + ""; parameter.put("timestamp", timestamp); String content = "appkey=" + appkey + "&appsecret=" + appsecret + "&nonce=" + nonce + "×tamp=" + timestamp; parameter.put("sign", EncryptHelper.sha(content)); ResponseMessage responseMessage = this.allMethod(parameter, GET_ACCESS_TOKEN, waterManageAccessToken); if (0 == responseMessage.getStatus()) { Map map = (Map) responseMessage.getMessage(); waterManageAccessToken = MapUtils.getString(map, "access_token"); redisTemplate.opsForValue().set("watermanage_access_token", waterManageAccessToken, 7200, TimeUnit.SECONDS); return waterManageAccessToken; } else { this.logger.info("请求业务接口获取access_token异常 ==> " + responseMessage.getErrmsg()); throw new Exception("请求业务接口获取access_token异常 ==> " + responseMessage.getErrmsg()); } } return waterManageAccessToken; } /** * @Description * @date 2020-07-15 * 接入资源业务系统 * 获取access_token保存至redis中,设置有效时长7200秒, */ public String getAccessTokenDingChuan(String dingChuanAppkey, String dingChuanAppsecret) throws Exception { // 获取waterManageAccessToken,如果为空,则请求waterManageAccessToken,保存至redis,时长为7300秒,过期后需重新生成放入 String waterManageAccessToken = (String) redisTemplate.opsForValue().get("ding_chuan_token"); logger.info("watermanage_access_token是否为空:" + waterManageAccessToken); if (StringUtils.isBlank(waterManageAccessToken)) { Map parameter = new HashMap<>();//添加参数 parameter.put("appkey", dingChuanAppkey); String nonce = UuidUtil.genernateNonce(8); parameter.put("nonce", nonce); String timestamp = System.currentTimeMillis() + ""; parameter.put("timestamp", timestamp); String content = dingChuanAppkey + dingChuanAppsecret + nonce + timestamp; parameter.put("sign", EncryptHelper.sha(content)); ResponseMessage responseMessage = this.allMethodDingChuan(parameter, "/api/open/auth/getToken", waterManageAccessToken, "https://sldc.dcyun.com:38266/supervisepc"); if (0 == responseMessage.getStatus()) { Map map = (Map) responseMessage.getMessage(); waterManageAccessToken = MapUtils.getString(map, "token"); redisTemplate.opsForValue().set("ding_chuan_token", waterManageAccessToken, 7200, TimeUnit.SECONDS); return waterManageAccessToken; } else { this.logger.info("请求业务接口获取access_token异常 ==> " + responseMessage.getErrmsg()); throw new Exception("请求业务接口获取access_token异常 ==> " + responseMessage.getErrmsg()); } } return waterManageAccessToken; } /** * @Description请求数据 * @date 2020-07-15 */ public ResponseMessage allMethod(Map map, String url, String watermanage_access_token) { ResponseMessage responseMessage = new ResponseMessage(""); try { //(1)每个appkey调用单个接口的频率不可超过5次/秒,否则返回错误码701401。 //(2)每个appkey调用单个接口的频率不可超过300次/分,否则返回错误码701402。 //(3)每个appkey调用多个接口的频率不可超过500次/分,否则返回错误码701403。 //(4)如果有具体接口调用频次限制,以接口调用频次为准。 Thread.sleep(230); HttpHeaders headers = new HttpHeaders(); if (StringUtils.isNotBlank(watermanage_access_token)) { headers.add("watermanage_access_token", watermanage_access_token); } headers.setContentType(MediaType.APPLICATION_JSON_UTF8); HttpEntity> strEntity; if (null != map) { strEntity = new HttpEntity<>(map, headers); } else { strEntity = new HttpEntity<>(headers); } RestTemplate restTemplate = new RestTemplate(); this.logger.info("访问接口:url=" + url); String allMethod = restTemplate.postForObject(baseurl + url, strEntity, String.class); responseMessage = JsonHelper.json2Object(allMethod, ResponseMessage.class); return responseMessage; } catch (InterruptedException e) { this.logger.error("睡眠等待过程异常", e); return new ResponseMessage(-1, "睡眠等待过程报错"); } catch (Exception e) { this.logger.error("访问水管平台报错" + url + "---" + e.getMessage().toString()); return new ResponseMessage(-1, "访问水管平台报错"); } } /** * @Description请求数据 * @date 2020-07-15 */ public ResponseMessage allMethodDingChuan(Map map, String url, String watermanage_access_token, String dingChuanUrl) { ResponseMessage responseMessage = new ResponseMessage(""); try { Thread.sleep(230); Map headers = new HashMap<>(); if (StringUtils.isNotBlank(watermanage_access_token)) { headers.put("token", watermanage_access_token); } headers.put("Content-Type", "application/json"); //String allMethod = restTemplate.postForObject(dingChuanUrl + url, strEntity, String.class); String result = HttpHeadHelper.doPost(dingChuanUrl + url, map, headers); responseMessage = JsonHelper.json2Object(result, ResponseMessage.class); return responseMessage; } catch (InterruptedException e) { this.logger.error("睡眠等待过程异常", e); return new ResponseMessage(-1, "睡眠等待过程报错"); } catch (Exception e) { this.logger.error("访问水管平台报错" + url + "---" + e.getMessage().toString()); return new ResponseMessage(-1, "访问水管平台报错"); } } /** * 获取一个redis漫衍锁 * * @param lockKey 锁住的key * @param lockExpireMils 锁住的时长。若是超时未解锁,视为加锁线程殒命,其他线程可争取锁 * @return */ public boolean lock(String lockKey, long lockExpireMils) { return (Boolean) redisTemplate.execute((RedisCallback) connection -> { long nowTime = System.currentTimeMillis(); Boolean acquire = connection.setNX(lockKey.getBytes(), String.valueOf(nowTime + lockExpireMils + 1).getBytes()); if (acquire) { return Boolean.TRUE; } else { byte[] value = connection.get(lockKey.getBytes()); if (Objects.nonNull(value) && value.length > 0) { long oldTime = Long.parseLong(new String(value)); if (oldTime < nowTime) { //connection.getSet:返回这个key的旧值并设置新值。 byte[] oldValue = connection.getSet(lockKey.getBytes(), String.valueOf(nowTime + lockExpireMils + 1).getBytes()); //当key不存时会返回空,示意key不存在或者已在管道中使用 return oldValue == null ? false : Long.parseLong(new String(oldValue)) < nowTime; } } } return Boolean.FALSE; }); } }