【问题标题】:Gson parse response to get generic classGson 解析响应以获取通用类
【发布时间】:2019-01-19 20:58:41
【问题描述】:

我有一个响应类

public class ResponseModel<T> {
    private boolean isRequestSuccessful;

    public boolean getIsRequestSuccessful() {
        return this.isRequestSuccessful;
    }

    public void setIsRequestSuccessful(boolean isRequestSuccessful) {
        this.isRequestSuccessful = isRequestSuccessful;
    }

    private String message;

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    private T object;

    public T getObject() {
        return this.object;
    }

    public void setObject(T object) {
        this.object = object;
    }
}

我的 API 将返回类型 T。我想解析来自 API 的响应并创建一个 ResponseModel 类型的对象。

我正在尝试实现类似下面的内容,我可以使用 c# 轻松完成。请帮助了解如何使用 Java 执行此操作

public static ResponseModel<T> Get(String requestUri) throws ClientProtocolException,IOException {
    CloseableHttpClient client = HttpClientBuilder.create().build();
    HttpGet httpGet = new HttpGet(requestUri);
    httpGet.addHeader("TenantKey", TenantKey);
    httpGet.addHeader("accept", "application/json");
    HttpResponse response = client.execute(httpGet);

    ResponseModel<T> responseModel = new ResponseModel<T>();

    if (response.getStatusLine().getStatusCode() == 200) {
        Gson gson = new GsonBuilder().create();
        // parse the response as T and and assign to object of ResponseModel 
        responseModel.object = ...
    }
    else
    {
        responseModel.message = response.getEntity().getContent();
    }
// return ResponseModel here
}

【问题讨论】:

  • 请考虑提供一些反馈,也许在某个时候点赞/接受。
  • @GhostCat 抱歉耽搁了,我用我的结果更新了问题
  • 当你有足够的内容来做一个好的自我回答时,只需写一个,然后接受它。将解决方案放入问题本身并不是解决问题的好方法。
  • @GhostCat 完成。谢谢!

标签: java json api apache-httpclient-4.x


【解决方案1】:

C# 和 Java 中的泛型非常不同。简单地说,你在这里做的事情毫无意义。

您使用的 java 泛型 T 有一个 编译 时间特性。它允许您在编译时使用更具体的类型,而不是到处使用Object

因此,您可能无法在“运行时”使用泛型来确定“T”,因为您可能打算这样做。您方法中的 T 来自“外部”,编译器 确定有时它应该是 ResponseModel&lt;Integer&gt;ResponseModel&lt;Whatever&gt; 在另一个上下文中。

您不能让 gson 读取 JSON 数据来为您返回特定的 ResponseModel&lt;Whatever&gt;。如果有的话,您也许可以使用TypeAdapter magic 根据实际值进行一些切换,以返回这个或那个特定 ResponseModel&lt;Foo&gt;

除此之外:当您使用 bean like 类作为您的 ResponseModel 时,您只希望它们是特定的,而不是通用的。

【讨论】:

    【解决方案2】:

    不确定,但我有类似的要求,但它适用于 Android。这是参考链接,我必须在其中编写一个通用类来从 Assets 文件夹加载不同形式的 JSON 并解析为 POJO 类。

    https://github.com/gokulnathperiasamy/Android-Helper/blob/master/JSONHelper.java

    代码:

        private static String convertJSONtoEntity(String jsonString, String typeString) {
            String jsonObjectString = null;
            try {
                JSONObject jsonObject = new JSONObject(jsonString);
                jsonObjectString = jsonObject.get(typeString).toString();
            } catch (Exception e) {
                Log.e(TAG, e.getLocalizedMessage());
            }
            return jsonObjectString;
        }
    
        private static <T> List<T> fromJsonList(String json, Class<T> clazz) {
            Object[] array = (Object[]) java.lang.reflect.Array.newInstance(clazz, 0);
            array = new Gson().fromJson(json, array.getClass());
            List<T> list = new ArrayList<>();
            if (array != null && array.length > 0) {
                for (Object anArray : array) {
                    list.add(clazz.cast(anArray));
                }
            }
            return list;
        }
    

    用法:

    使用jsonString 调用convertJSONtoEntity()typeString 将成为 JSON 的根元素。

    使用convertJSONtoEntity()Class 返回的值调用fromJsonList()。这给出了来自 JSON 的对象列表。

    【讨论】:

      【解决方案3】:

      在其他答案的帮助下并在谷歌中进一步搜索,我最终得到了以下代码

      public static <T> ResponseModel<T> Get(Class<?> classType, String requestUri) throws ClientProtocolException, IOException 
      {
          CloseableHttpClient client = HttpClientBuilder.create().build();
          HttpGet httpGet = new HttpGet(requestUri);
          httpGet.addHeader("accept", "application/json");
          HttpResponse response = client.execute(httpGet);
          ResponseModel<T> responseModel = new ResponseModel<T>();
          if (response.getStatusLine().getStatusCode() == 200) 
          {
              responseModel.setObject((T) Utils.fromJson(EntityUtils.toString(response.getEntity()), classType));
              responseModel.setIsRequestSuccessful(true);
          } 
          else 
          {
              responseModel.setMessage(response.getEntity().getContent().toString());
              responseModel.setIsRequestSuccessful(false);
          }
          return responseModel;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-10
        相关资源
        最近更新 更多