[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;
}
}