Explorar o código

测试assessToken

yaodeguang hai 1 mes
pai
achega
99d405422d

+ 11 - 0
pom.xml

@@ -21,6 +21,17 @@
     </properties>
 
     <dependencies>
+        <!-- Spring Data Redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <!-- 如果使用 Redis 连接池 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-thymeleaf</artifactId>

+ 14 - 0
src/main/java/cn/hnthyy/thmz/service/impl/his/jy/AccessToken.java

@@ -0,0 +1,14 @@
+//定义 Token 存储实体
+package cn.hnthyy.thmz.service.impl.his.jy;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AccessToken {
+    private String token;
+    private long expiresAt; // 过期时间戳(秒)
+}

+ 62 - 0
src/main/java/cn/hnthyy/thmz/service/impl/his/jy/ApiClient.java

@@ -0,0 +1,62 @@
+package cn.hnthyy.thmz.service.impl.his.jy;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+
+@Service
+public class ApiClient {
+    @Resource
+    private AssessTokenService assessTokenService;
+    @Resource
+    private RestTemplate restTemplate;
+    @Bean
+    public RestTemplate restTemplate(RestTemplateBuilder builder) {
+        return builder.build();
+    }
+
+    // 带 Token 自动刷新的 API 调用
+    public <T> T callApiWithToken(String url, Class<T> responseType, Object... params) {
+        AccessToken token = assessTokenService.getToken();
+        if (token == null || isTokenExpired(token)) {
+            refreshAndStoreToken();
+            token = assessTokenService.getToken();
+        }
+
+        try {
+            HttpHeaders headers = new HttpHeaders();
+            headers.set("Authorization", "Bearer " + token.getToken());
+            HttpEntity<?> entity = new HttpEntity<>(headers);
+
+            ResponseEntity<T> response = restTemplate.exchange(
+                    url,
+                    HttpMethod.GET,
+                    entity,
+                    responseType,
+                    params
+            );
+
+            return response.getBody();
+        } catch (HttpClientErrorException e) {
+            if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {
+                refreshAndStoreToken(); // Token 过期,刷新后重试
+                return callApiWithToken(url, responseType, params); // 递归重试(建议限制次数)
+            }
+            throw e;
+        }
+    }
+
+    private boolean isTokenExpired(AccessToken token) {
+        return System.currentTimeMillis() / 1000 >= token.getExpiresAt();
+    }
+
+    private void refreshAndStoreToken() {
+        AccessToken newToken = assessTokenService.fetchNewToken();
+        assessTokenService.storeToken(newToken);
+    }
+}

+ 22 - 0
src/main/java/cn/hnthyy/thmz/service/impl/his/jy/ApiController.java

@@ -0,0 +1,22 @@
+package cn.hnthyy.thmz.service.impl.his.jy;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api")
+public class ApiController {
+    @Autowired
+    private ApiClient apiClient;
+
+    @GetMapping("/data")
+    public String fetchData() {
+        String result = apiClient.callApiWithToken(
+                "https://api.example.com/data",
+                String.class
+        );
+        return "Data: " + result;
+    }
+}

+ 63 - 0
src/main/java/cn/hnthyy/thmz/service/impl/his/jy/AssessTokenService.java

@@ -0,0 +1,63 @@
+//封装AssessToken服务类
+package cn.hnthyy.thmz.service.impl.his.jy;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class AssessTokenService {
+    @Value("http://20.46.201.94:9999/auth/accesstoken/create?appId=saca_ivA9ipRTKJ&appSecret=YXCxOq4DUMuFfFrPs9dFKXPKT0PSjWzY")
+    private String tokenUrl;
+    @Value("saca_ivA9ipRTKJ")
+    private String appId;
+    @Value("YXCxOq4DUMuFfFrPs9dFKXPKT0PSjWzY")
+    private String appSecret;
+
+    @Resource
+    private RedisTemplate<String, AccessToken> redisTemplate;
+
+
+    private static final String TOKEN_KEY = "access_token";
+
+    // 获取新 Token(调用认证接口)
+    public AccessToken fetchNewToken() {
+        RestTemplate restTemplate = new RestTemplate();
+        Map<String, String> params = new HashMap<>();
+        params.put("grant_type", "client_credential");
+        params.put("appid", appId);
+        params.put("secret", appSecret);
+
+        ResponseEntity<Map> response = restTemplate.getForEntity(
+                tokenUrl + "?grant_type={grant_type}&appid={appid}&secret={secret}",
+                Map.class,
+                params
+        );
+
+        if (response.getStatusCode() == HttpStatus.OK) {
+            Map<String, Object> body = response.getBody();
+            String token = (String) body.get("access_token");
+            int expiresIn = (int) body.get("expires_in");
+            long expiresAt = System.currentTimeMillis() / 1000 + expiresIn - 300; // 提前5分钟过期
+            return new AccessToken(token, expiresAt);
+        }
+        throw new RuntimeException("Failed to fetch token");
+    }
+
+    // 存储 Token 到 Redis
+    public void storeToken(AccessToken token) {
+        redisTemplate.opsForValue().set(TOKEN_KEY, token);
+    }
+
+    // 从 Redis 获取 Token
+    public AccessToken getToken() {
+        return redisTemplate.opsForValue().get(TOKEN_KEY);
+    }
+}

+ 22 - 0
src/main/java/cn/hnthyy/thmz/service/impl/his/jy/TokenRefreshScheduler.java

@@ -0,0 +1,22 @@
+// 配置定时任务刷新 Token
+package cn.hnthyy.thmz.service.impl.his.jy;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+@EnableScheduling
+@Configuration
+public class TokenRefreshScheduler {
+    @Autowired
+    private AssessTokenService assessTokenService;
+
+    // 每23小时执行一次(早于24小时过期时间)
+    @Scheduled(fixedRate = 23 * 60 * 60 * 1000)
+    public void refreshToken() {
+        AccessToken newToken = assessTokenService.fetchNewToken();
+        assessTokenService.storeToken(newToken);
+        System.out.println("Token refreshed: " + newToken.getToken());
+    }
+}

+ 11 - 1
src/main/resources/application-dev.yml

@@ -19,6 +19,16 @@ server:
   servlet:
     context-path: "/thmz"
 spring:
+  redis:
+    host: localhost     # Redis 服务器地址
+    port: 6379         # 默认端口
+    password:          # 密码(若无则省略)
+    database: 0        # 默认数据库索引
+    lettuce:
+      pool:
+        max-active: 8  # 连接池最大连接数
+        max-idle: 4    # 连接池最大空闲连接
+        min-idle: 1    # 连接池最小空闲连接
   #jackson:
     #date-format: "yyyy-MM-dd HH:mm:ss"
     #设置为东八区时间
@@ -188,7 +198,7 @@ soap_url: "http://172.16.32.178:622/pushservice.asmx?wsdl"
 webSocketHost: "ws://172.16.30.119:8089/thmz/"
 
 #门诊结算单地址  http://webhis.thyy.cn:8080
-mzjsdHost: http://172.16.30.119:3000
+mzjsdHost: http://localhost:3000
 
 #websocket 药房地址前半部分 172.16.32.161
 webSocketPrescriptionHost: "ws://172.16.30.119:9000/"