OkHttp全局拦截器设置token超时重新获取
2021-01-23 22:13
标签:boolean ret empty 时间设置 content request cas read ref Feign客户端请求远程服务接口时,需要携带token进行认证(详见《微服务迁移记(六):集成jwt保护微服务接口安全》),token有超时时间设置,当超时后,需要重新刷新token。如果每个接口都去判断,那就费事了,最好的办法是在拦截器里做。我这里使用的是OkHttp,新增一个OkHttpInterceptor的拦截器: 注意,这里不需要加@Components,因为我在这个控制器里有注入Service和RedisUtil以及配置项,如果直接扫包方式载入,会造成注入对象为null的错误。具体原因是拦截器是在Springcontext之前加载。 新增一个Okhttp的配置类: 配置这个类时,我一开始犯了一个错误,抄了网上一段代码,直接在增加拦截器时使用了: 这种方式和为拦截器加注解一样,并不能提前加载拦截器,所以需要如上面的代码,将拦截器独立出来一个bean,将这个bean加入到okhttp即可。 OkHttp全局拦截器设置token超时重新获取 标签:boolean ret empty 时间设置 content request cas read ref 原文地址:https://www.cnblogs.com/zhouyu629/p/13276370.html@Slf4j
public class OkHttpInterceptor implements HandlerInterceptor,Interceptor {
@Autowired
private ApiInitService apiInitService;
@Autowired
private RedisUtil redisUtil;
@Value("${app_id}")
String app_id;
@Value("${app_secret}")
String app_secret;
@Override
public Response intercept(Chain chain) throws IOException {
log.info("进入okhttp拦截器");
Request request = chain.request();
try {
Response response = chain.proceed(request);
ResponseBody responseBody = response.body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE);
Buffer buffer = source.getBuffer();
MediaType mediaType = responseBody.contentType();
if(isPlaintext(buffer)){
Charset charset = Charset.forName("UTF-8");
String result = buffer.clone().readString(mediaType.charset(charset));
log.info("result:"+result);
//如果token超时或不存在,则重新获取
ResponseData responseData = JSONObject.parseObject(result,ResponseData.class);
if(responseData.getCode() == CodeEnum.UNKNOWNTOKEN.getCode()){
//重新获取token
String tokenData = this.apiInitService.getToken(app_id,app_secret);
if(StringUtils.isNotEmpty(tokenData)){
//重新将token存到redis中
redisUtil.set("Authorization",tokenData);
}
}
}
return response;
}catch (Exception e){
throw e;
}
}
/**
* Returns true if the body in question probably contains human readable text. Uses a small sample
* of code points to detect unicode control characters commonly used in binary file signatures.
*/
static boolean isPlaintext(Buffer buffer) throws EOFException {
try {
Buffer prefix = new Buffer();
long byteCount = buffer.size() ;
buffer.copyTo(prefix, 0, byteCount);
for (int i = 0; i ) {
if (prefix.exhausted()) {
break;
}
int codePoint = prefix.readUtf8CodePoint();
if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
return false;
}
}
return true;
} catch (EOFException e) {
return false; // Truncated UTF-8 sequence.
}
}
private boolean bodyEncoded(Headers headers) {
String contentEncoding = headers.get("Content-Encoding");
return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity");
}
}
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
@Slf4j
public class OkHttpClientConfig {
private OkHttpClient okHttpClient;
@Bean
public OkHttpInterceptor okHttpInterceptor(){
return new OkHttpInterceptor();
}
@Bean
public okhttp3.OkHttpClient okHttpClient(OkHttpClientFactory okHttpClientFactory,
FeignHttpClientProperties httpClientProperties) {
this.okHttpClient = okHttpClientFactory.createBuilder(httpClientProperties.isDisableSslValidation()).connectTimeout(httpClientProperties.getConnectionTimeout(),TimeUnit.SECONDS)
.followRedirects(httpClientProperties.isFollowRedirects())
.addInterceptor(okHttpInterceptor())
.build();
return this.okHttpClient;
}
}
.addInterceptor(new OkHttpInterceptor())
上一篇:建立网站的步骤
下一篇:js实现左侧弹出效果
文章标题:OkHttp全局拦截器设置token超时重新获取
文章链接:http://soscw.com/index.php/essay/46051.html