使用Unirest时,如何用Jackson将JSONArray转为泛型对象数组?
解决方案
首先定义通用的泛型响应类:
public class RestResponse<T> { private boolean success; private String message; private T data; // 生成getter、setter,或用Lombok的@Data注解简化 }
方案1:用Jackson直接解析响应字符串(推荐)
跳过Unirest的asObject,直接获取响应体字符串,结合Jackson的TypeReference处理泛型:
// 发送请求获取响应字符串 String responseBody = Unirest.get("your-api-url") .asString() .getBody(); // 用Jackson解析为泛型响应 ObjectMapper objectMapper = new ObjectMapper(); RestResponse<ArrayList<MyObject>> response = objectMapper.readValue( responseBody, new TypeReference<RestResponse<ArrayList<MyObject>>>() {} ); // 直接使用正确类型的data ArrayList<MyObject> dataList = response.getData();
这种方式完全不需要创建冗余的非泛型类,通过TypeReference明确泛型的具体类型,Jackson就能正确将data字段解析为目标集合。
方案2:将org.json.JSONArray转为目标集合
如果已经通过asJson()拿到了org.json.JSONArray,可以用Jackson直接转换:
// 假设已从响应中取出data对应的JSONArray org.json.JSONArray jsonArray = jsonObject.getJSONArray("data"); ObjectMapper objectMapper = new ObjectMapper(); // 转字符串后解析,Jackson处理效率足够,无需担心性能问题 ArrayList<MyObject> dataList = objectMapper.readValue( jsonArray.toString(), new TypeReference<ArrayList<MyObject>>() {} );
若觉得转字符串不够优雅,也可以通过节点转换实现:
JsonNode jacksonNode = objectMapper.readTree(jsonArray.toString()); ArrayList<MyObject> dataList = objectMapper.convertValue( jacksonNode, new TypeReference<ArrayList<MyObject>>() {} );
方案3:配置Unirest使用Jackson作为ObjectMapper(从根源解决)
Unirest默认的ObjectMapper无法正确处理泛型,自定义配置后可直接用泛型版本的解析逻辑:
// 配置Unirest使用Jackson的ObjectMapper Unirest.config().setObjectMapper(new ObjectMapper() { private final com.fasterxml.jackson.databind.ObjectMapper jacksonMapper = new com.fasterxml.jackson.databind.ObjectMapper(); @Override public <T> T readValue(String value, Class<T> valueType) { try { return jacksonMapper.readValue(value, valueType); } catch (IOException e) { throw new RuntimeException("JSON解析失败", e); } } @Override public String writeValue(Object value) { try { return jacksonMapper.writeValueAsString(value); } catch (JsonProcessingException e) { throw new RuntimeException("对象序列化失败", e); } } // 新增泛型解析方法,支持TypeReference public <T> T readValue(String value, TypeReference<T> typeRef) throws IOException { return jacksonMapper.readValue(value, typeRef); } }); // 封装泛型请求方法 public static <T> RestResponse<T> getGenericResponse(String url, TypeReference<RestResponse<T>> typeRef) { String responseBody = Unirest.get(url).asString().getBody(); try { return ((com.fasterxml.jackson.databind.ObjectMapper) Unirest.config().getObjectMapper()) .readValue(responseBody, typeRef); } catch (IOException e) { throw new RuntimeException(e); } } // 使用示例 RestResponse<ArrayList<MyObject>> response = getGenericResponse( "your-api-url", new TypeReference<RestResponse<ArrayList<MyObject>>>() {} );
配置后,Unirest的JSON解析逻辑会使用Jackson,泛型解析就能正常工作。
内容的提问来源于stack exchange,提问作者Joseph Larson
相关产品推荐
相关产品推荐

