OKhttp可以通过拦截器对每个请求设置单独的请求时间,具体代码如下:
private static class ResetTimeoutInterceptor implements Interceptor{
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request request = chain.request();
String connectTimeout = request.header(RESET_CONNECT_TIMEOUT);
if(StringUtils.isNotBlank(connectTimeout)){
chain = chain.withConnectTimeout(Integer.parseInt(connectTimeout),TimeUnit.SECONDS);
}
String readTimeout = request.header(RESET_READ_TIMEOUT);
if(StringUtils.isNotBlank(readTimeout)){
chain = chain.withReadTimeout(Integer.parseInt(readTimeout),TimeUnit.SECONDS);
}
String writeTimeout = request.header(RESET_WRITE_TIMEOUT);
if(StringUtils.isNotBlank(writeTimeout)){
chain = chain.withWriteTimeout(Integer.parseInt(writeTimeout),TimeUnit.SECONDS);
}
return chain.proceed(request);
}
}
读取header中的超时时间配置,调用chain方法设置相关请求超时时间。代码改造完成之后,运行出现类似如下报错:
java.lang.NoSuchMethodError: okhttp3.Interceptor$Chain.withConnectTimeout
典型的NoSuchMethodError错误,一般情况下都是jar包冲突引起的,检查IDEA的jar包依赖,果然有发现:
依赖中存在两个okhttp的版本。查询相关资料
withConnectTimeout3xx版本中是不支持的,很明显java在运行的时候加载错了版本。很自然的想法排除3xx版本的okhttp。
移除工程指定版本jar
maven exclusions标签
一般简单的工程可以直接使用exclusions标签来移除冲突的jar包,但是工程结构复杂,在父子pom配置中,各个子pom也存在相互的依赖,此种情况下通过exclusions来排除指定依赖非常复杂,尝试多次仍然失败之后,放弃该方法。
maven插件
调研相关maven插件,找到maven enforce plugin插件,该插件主要用来校验pom的配置是否符合规范,同时也提供依赖排除与依赖引入等相关功能,感兴趣的同学可以在访问官网。在父pom文件中引入配置如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>enforce-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedPlugins>
<level>ERROR</level>
<excludes>
<exclude>com.squareup.okhttp3:okhttp:3.8.1</exclude>
</excludes>
<message>Please consider using the maven-invoker-plugin (http://maven.apache.org/plugins/maven-invoker-plugin/)!</message>
<includes>
<include>com.squareup.okhttp3:okhttp:4.9.0</include>
</includes>
</bannedPlugins>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
在父pom下执行maven命令,并没有排除冲突的jar包,具体原因未知,后续有时间在研究一下。
依赖优先级
既然方法一和方法二都失败了,考虑第三种方式maven加载依赖包是有优先级和顺序的,只要引入的jar的包优先级高于冲突jar包的优先级一样可以解决问题。具体参考这篇博客 具体实现,在父pom中指定okhttp的版本覆盖3xx的版本,在子pom中引用父pom中的jar包。修改如下:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.3.70</version>
</dependency>
重新reimport一下pom文件,新的依赖如下:
冲突jar包被移除了,问题修复!!!