You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OkHttpClient结合Model解析API数据时出现空指针错误求助

OkHttpClient请求API空指针问题排查

我使用OkHttpClient拉取API数据,目标接口为https://dummyjson.com/products,已创建如下TestModel类(字段已添加getter和setter方法,未展示):

public class TestModel {

    public class ProductList {
        private List<Product> products;
        private int total;
        private int skip;
        private int limit;
    }

    public class Product {
        private int id;
        private String title;
        private String description;
        private double price;
        private double discountPercentage;
        private double rating;
        private int stock;
        private String brand;
        private String category;
        private String thumbnail;
        private List<String> images;
    }
}

编写以下请求代码后出现空指针错误,排除数据为空的可能,请求排查问题:

private final OkHttpClient client = new OkHttpClient();

public void GetFromServer(String _serviceUrl) throws Exception {
    String absoluteUrl = baseUrl + "/" + _serviceUrl;
    Request request = new Request.Builder()
            .url(absoluteUrl)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override public void onFailure(Call call, IOException e) {
            Logging.Error("GetFromServer is Failure. Endpoint : " + absoluteUrl + " Error Message : " + e.getMessage());
            e.printStackTrace();
        }
        @Override public void onResponse(Call call, Response response) throws IOException {
            try (ResponseBody responseBody = response.body()) {
                if (response.isSuccessful()) {
                    String json = response.body().string();

                    Gson gson = new Gson();
                    TestModel.ProductList productList = gson.fromJson(json, TestModel.ProductList.class);

                    List<TestModel.Product> products = productList.getProducts();
                    for (TestModel.Product product : products) {
                        System.out.println("Product Title: " + product.getTitle());
                        System.out.println("Description: " + product.getDescription());
                       
                    }
                }
                else {
                    throw new IOException("Unexpected code " + response);
                }
            }
        }
    });
}

问题原因及解决方案

1. 重复调用response.body().string()导致JSON为空

ResponseBody的string()方法只能调用一次,第二次调用会返回null。代码中先通过try (ResponseBody responseBody = response.body())获取了响应体,随后又调用response.body().string(),此时响应体已被消耗,返回null,导致Gson解析出的productList为null,后续调用productList.getProducts()触发空指针。

修复代码:

// 改用已获取的responseBody调用string()
String json = responseBody.string();

2. 非静态内部类无法被Gson实例化

ProductList和Product是TestModel的非静态内部类,非静态内部类依赖外部类实例才能创建,Gson默认无法直接实例化这类类,会导致解析失败,productList为null,触发空指针。

修复代码:将内部类改为静态内部类

public class TestModel {
    // 改为静态内部类
    public static class ProductList {
        private List<Product> products;
        private int total;
        private int skip;
        private int limit;
        // getter/setter
    }

    // 改为静态内部类
    public static class Product {
        private int id;
        private String title;
        private String description;
        private double price;
        private double discountPercentage;
        private double rating;
        private int stock;
        private String brand;
        private String category;
        private String thumbnail;
        private List<String> images;
        // getter/setter
    }
}

3. URL拼接可能存在格式错误

直接用字符串拼接URL可能出现双斜杠(比如baseUrl末尾已有/,拼接后变成https://dummyjson.com//products),虽然多数服务器会兼容,但可能导致请求异常。建议用OkHttp的HttpUrl构建URL,避免拼接错误:

修复代码:

// 替换原URL拼接逻辑
HttpUrl url = HttpUrl.parse(baseUrl).newBuilder()
        .addPathSegment(_serviceUrl)
        .build();
Request request = new Request.Builder()
        .url(url)
        .build();

内容的提问来源于stack exchange,提问作者avcismail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:13:14