[springCloud 随笔] 先获取token再调用接口的常见写法

对于项目中常见的先获取token, 然后再调用接口的方式, 通常feignClient可以这么写:

  • 首先写获取token的feignClient:

其中, 指定feignClient的url, 和配置类(内部类, 其中要传递loglevel, requestInterceptor要拦截添加header)

对于x-www-form-urlencoded表单加密类型的比较特殊, 传参需要一个Map的param来传递

@FeignClient(name = "TokenFeignClient", url = "${token.url}", configuration =
        TokenConfig.class)
public interface TokenFeignClient {

    class TokenConfig {

        @Bean
        @Primary
        Logger.Level loggerLevel() {
            return Logger.Level.FULL;
        }

        @Bean
        public RequestInterceptor headerInterceptor() {
            return template -> template
                    .header(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
        }
    }

    @ApiOperation("get token")
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    TokenResponse getToken(@RequestParam Map<String, String> request);
}
  • 获取到之后, 设置缓存时间
@Slf4j
@Service
@RequiredArgsConstructor
public class MyService {

    private static final String BEARER = "Bearer ";
    private final Properties properties;
    private final TokenFeignClient tokenFeignClient;


    @Cacheable(key = "TOKEN", timeout = CommonConstants.FIFTY, timeUnit = TimeUnit.MINUTES)
    public String getToken() {
        Map<String, String> request = new HashMap<>();
        request.put(paramKey, properties.getParamValue);//add header
        TokenResponse tokenResponse;
        try {
            tokenResponse = TokenFeignClient.getToken(request);
        } catch (Exception e) {
            log.error(" get token error", e);
            throw new RuntimeException();
        }
        return BEARER + tokenResponse.getAccessToken();
    }
}
  • 获取的token添加到下一个feignclient里面,此feignClient用于获取到项目中用的内容,例如获取一个项目中要使用的code
@FeignClient(name = "CodeFeignClient", url = "${code.url}", configuration =
        CodeConfig.class)
public interface CodeFeignClient {

    class CodeConfig {
        @Bean
        @Primary
        Logger.Level loggerLevel() {
            return Logger.Level.FULL;
        }

        @Bean
        public RequestInterceptor headerInterceptor(MyService myService, CodeProperties props) {
            return template -> template
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                    .header(HttpHeaders.AUTHORIZATION, myService.getToken())
                    .header(header_key, props.getValue();
        }
    }

    @ApiOperation("get code")
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    CodeResponse getCode(@RequestBody Object object);
}
  • 如果项目中有配置文件需要读取, 可以写到类中读取
@Data
@Configuration
@ConfigurationProperties(prefix = "code")
public class CodeProperties {
    private CodeConfigSection token;

    @Data
    public static class CodeConfigSection {
        private String url;
        private String clientId;
        private String clientSecret;
    }
}
posted @ 2023-03-16 14:27  Roy2048  阅读(393)  评论(0)    收藏  举报