最近在开发后端接口,需要调用EBS
,说实话,这个EBS
返回的数据格式真的搞得好复杂。
为什么说复杂呢?因为返回的数据不止是嵌套得很深,而且还是二维数组,当然,还是要眼见为实
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| { "OutputParameters": { "O_COMMENTS": "xxxxxx", "O_ERRORCODE": "", "O_ERRORINFO": "", "O_RESULT": "0", "O_SYS_REFCUR": { "Row": [ { "Column": [ { "col1": "xx" }, { "col2": "1" }, { "col3": "" }, { "col4": "5375" } ] }, { "Column": [ { "col1": "xx" }, { "col2": "1" }, { "col3": "" }, { "col4": "5379" } ] } ] } } }
|
当然还有更复杂的结构。
强大的fastjson
一般我们的json是比较规则的对象,但是他这个是动态的二维数组,而且节点也比较深,所以这里就需要用到fastjson
中的JSONPath
和JSONArray
,我这里是先用JSONPath.eval
把Row
节点的数据转为JSONArray
,再将其转为Map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public static HashMap<String, String> ebsJsonResult2Map(JSONArray jsonArray) { HashMap<String, String> hashMap = new HashMap<>(); if (ObjectUtils.isEmpty(jsonArray)) { return hashMap; } jsonArray.stream().forEach(jsonObject -> { JSONObject object = (JSONObject) jsonObject; Iterator<String> it = object.keySet().iterator(); while (it.hasNext()) { String key = it.next(); hashMap.put(key, object.getString(key)); } }); return hashMap; }
public static <T> T ebsJsonResult2Object(JSONArray jsonArray, Class<T> tClass) { Map map = ebsJsonResult2Map(jsonArray); return JSONObject.parseObject(JSONObject.toJSONString(map), tClass); }
public static <T> List<T> ebsJsonRows2Object(JSONArray jsonArray,Class<T> tClass) { HashMap<String, JSONObject> hashMap = new HashMap<>(); if (ObjectUtils.isEmpty(jsonArray)) { return new ArrayList<>(); } List<T> result=new ArrayList<>(); jsonArray.stream().forEach(jsonObject -> { JSONObject object = (JSONObject) jsonObject; result.add(ebsJsonResult2Object(object.getJSONArray("Column"),tClass)); }); return result; }
|
然后这里我就可以调用这些方法序列化为List对象
1 2 3 4 5 6
| JSONArray jsonArray = (JSONArray) JSONPath.eval(JSONObject.parseObject(response), "$.OutputParameters.O_SYS_REFCUR.Row"); if (ObjectUtils.isEmpty(jsonArray)) { throw new BusinessException("未获取到xxxxxxx."); }
List<AgreementProductsVo> productsVo = EBSJsonUtil.ebsJsonRows2Object(jsonArray, AgreementProductsVo.class);
|
当然啦,强大的JSONPath
不可能就只会这么用,来https://github.com/alibaba/fastjson/wiki/JSONPath看看。
好用的Http请求工具类
在Java中,常用的Http请求类型确实不少,比如okhttp
、hutool
、retrofit
。但是这里,我要介绍的是unirest-java
,这个类库使用起来也是非常方便,直接引入依赖包即可进行链式调用。
1 2 3 4 5
| <dependency> <groupId>com.konghq</groupId> <artifactId>unirest-java</artifactId> <version>3.7.00</version> </dependency>
|
然后在程序里面可以这样优雅的使用
1 2 3 4 5 6 7 8 9 10 11 12
| HttpResponse<JsonNode> response = Unirest.post("http://httpbin.org/post") .header("accept", "application/json") .queryString("apiKey", "123") .field("parameter", "value") .field("firstname", "Gary") .asJson();
Unirest.get("http://httpbin.org") .queryString("fruit", "apple") .queryString("droid", "R2D2") .asString();
|
更多功能,可以去http://kong.github.io/unirest-java/看看。
Http请求乱码
调用接口测试时,我都是用的junit进行的单元测试,在单元测试的时候没有问题,用IDEA
通过Tomcat
的方式,请求出来的数据居然是乱码了。没办法只有百度,百度对我说,需要在Tomcat下面的catalina.bat
配置一个参数-Dfile.encoding=UTF-8
。这里我是这样配置的
1
| set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dfile.encoding=UTF-8"
|
但是加入这个参数后,在IDEA的控制台又会出来乱码,这里也需要在IDEA配置一下:
Help->Edit Custome VM Options
加入