Retrofit XML解析中onResponse未触发,内部类构造报错求排查
我来帮你分析下问题所在,核心原因出在Dealer这个内部类的定义上,另外你没实现onFailure方法也导致你一开始没看到具体错误信息,误以为只是onResponse没被调用。
问题1:非静态内部类无法被SimpleXML转换器实例化
你的Dealer是ApiResponse的非静态内部类,这种类的实例化必须依赖于外部类ApiResponse的实例。但SimpleXML转换器在解析XML时,是直接通过反射创建Dealer对象的,它没有办法先创建ApiResponse实例再去创建Dealer,所以会抛出「无法构造内部类」的异常,这直接导致请求失败,不会进入onResponse方法。
解决方法:把Dealer改成静态内部类
只需要给Dealer类加上static修饰符,让它变成静态内部类,这样它就不再依赖外部类的实例,可以被独立实例化:
@Root(name = "dealers", strict = false) public class ApiResponse { @ElementList(inline = true) public List<Dealer> dealerList; // 添加static修饰符 @Root(name = "dealer") public static class Dealer { @Element(name = "name") private String name; @Element(name = "google_static_map_url") private String staticMapUrl; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStaticMapUrl() { return staticMapUrl; } public void setStaticMapUrl(String staticMapUrl) { this.staticMapUrl = staticMapUrl; } } }
问题2:未实现onFailure方法,无法排查错误
你之前的enqueue只实现了onResponse,没有处理失败的情况,所以当请求出错时,你看不到任何错误提示,误以为只是onResponse没触发。一定要实现onFailure方法,它能帮你快速定位请求失败的原因。
完善后的请求代码
给你的请求代码补上onFailure,同时增加一些健壮性判断(比如响应是否成功、body是否为空):
private void getDealerList() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(API_BASE_URL) .client(new OkHttpClient()) .addConverterFactory(SimpleXmlConverterFactory.create()) .build(); MapAPI dealerApiKey = retrofit.create(MapAPI.class); Call<ApiResponse> callResponse = dealerApiKey.getList("55082"); callResponse.enqueue(new Callback<ApiResponse>() { @Override public void onResponse(Call<ApiResponse> call, Response<ApiResponse> mResponse) { // 先判断响应是否成功,body是否非空 if (mResponse.isSuccessful() && mResponse.body() != null) { mDealerList = mResponse.body().dealerList; // 注意这里要引用静态内部类:ApiResponse.Dealer ArrayList<ApiResponse.Dealer> dealerArrayList = new ArrayList<>(mDealerList); adapter = new StoreListAdapter(dealerArrayList, getApplicationContext()); mRecyclerView.setAdapter(adapter); } else { // 处理响应不成功的情况,比如打印状态码 Log.e("DealerRequest", "请求失败,状态码:" + mResponse.code()); } } @Override public void onFailure(Call<ApiResponse> call, Throwable t) { // 打印错误栈信息,方便排查 t.printStackTrace(); // 给用户一个友好提示 Toast.makeText(getApplicationContext(), "获取经销商列表失败:" + t.getMessage(), Toast.LENGTH_SHORT).show(); } }); }
额外注意事项
- 检查XML结构与注解匹配:确认你的XML响应结构是
<dealers>下直接包含多个<dealer>元素,@ElementList(inline = true)的使用是正确的,它表示列表元素直接内嵌在根元素下,不需要额外的包裹标签。 - 确认BaseUrl格式:Retrofit对BaseUrl的格式有要求,如果你的BaseUrl以
/结尾,那么@GET的路径不能以/开头(你的@GET("/dealer")如果BaseUrl是https://xxx.com/的话,拼接后是https://xxx.com/dealer,是正确的;如果BaseUrl没有以/结尾,比如https://xxx.com,拼接后会变成https://xxx.comdealer,这就会出错,所以要保证BaseUrl的格式正确)。
内容的提问来源于stack exchange,提问作者user9113609
相关产品推荐
相关产品推荐

