Retrofit GET请求抛出NoSuchMethodError问题求助
NoSuchMethodError的问题 先看一下你遇到的错误:
Exception in thread "main" java.lang.NoSuchMethodError: okio.BufferedSource.rangeEquals(JLokio/ByteString;)Z
at okhttp3.internal.Util.bomAwareCharset(Util.java:431)
at okhttp3.ResponseBody$BomAwareReader.read(ResponseBody.java:249)
at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1295)
at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1333)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:549)
at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:74)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:119)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:218)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
at com.retrofitexample.demo.login.BrandRepoImp.getBrandList(BrandRepoImp.java:27)
at com.retrofitexample.demo.login.BrandRepoImp.main(BrandRepoImp.java:17)
Process finished with exit code 1
嘿,这个问题我之前踩过坑!报错的核心原因是OkHttp/Okio的版本冲突,同时你的实体类还有个小细节需要调整,下面一步步来解决:
一、核心问题:Okio版本冲突
这个NoSuchMethodError说明你的项目里同时存在不同版本的Okio依赖——Retrofit依赖的Okio版本和你项目中其他依赖引入的Okio版本不一致,导致运行时找不到正确的方法。POST请求能正常运行可能是因为POST的响应解析逻辑没有触发这个冲突的方法,而GET请求的集合反序列化刚好触发了。
解决步骤:
统一Retrofit与OkHttp/Okio的版本
确保你引入的Retrofit、OkHttp、Okio版本是兼容的,比如Retrofit 2.9.0对应OkHttp 4.9.0+,Okio 2.9.0+。如果是Gradle项目,你可以直接用Retrofit的BOM来自动管理兼容版本:dependencies { implementation platform('com.squareup.retrofit2:retrofit-bom:2.9.0') implementation 'com.squareup.retrofit2:retrofit' implementation 'com.squareup.retrofit2:converter-gson' implementation 'com.squareup.okhttp3:okhttp' }Maven项目则可以手动指定所有相关依赖的统一版本号。
排查并排除冲突依赖
用依赖分析工具找出引入旧版Okio的依赖:- Gradle项目执行命令:
./gradlew dependencies - Maven项目执行命令:
mvn dependency:tree
找到冲突的依赖后,在对应的依赖声明中排除旧版Okio,比如:
implementation('com.example:some-third-party-lib:1.0.0') { exclude group: 'com.squareup.okio', module: 'okio' }- Gradle项目执行命令:
二、实体类的潜在问题
你的Brand类目前只有带参构造函数,而Gson默认需要无参构造函数来完成反序列化操作,虽然这次报错不是因为这个,但后续很可能会引发反序列化失败的问题,建议补充无参构造和getter/setter:
public class Brand { private String id; private String name; // 新增无参构造,Gson反序列化必需 public Brand() {} public Brand(String id, String name) { this.id = id; this.name = name; } // 添加getter和setter,Gson需要访问属性 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
三、检查请求路径是否正确
另外,注意你的Service接口的GET注解路径:你设置的baseUrl是http://example.com/grc/main/,而@GET("/brands")的斜杠开头会覆盖baseUrl的路径部分,最终请求地址会变成http://example.com/brands。如果实际接口路径是http://example.com/grc/main/brands,应该把注解改成@GET("brands")(去掉开头的斜杠)。
内容的提问来源于stack exchange,提问作者Morbidity

