Hutool工具向第三方的接口发起请求

发布时间 2023-08-08 16:05:40作者: 角刀牛Java

使用Hutool工具请求第三方接口遇到的一篮子问题
1. 请求第三方接口的几种方式
1.1 使用HttpUtil请求,返回String类型的JSON串
一般用在请求普通的页面情况下,返回的结果是JSON格式,但是如果出现了404、504错误,返回的是HTML格式报错(视情况而定)

示例代码(来源于Hutool的开发文档):

Get请求:

// 最简单的HTTP请求,可以自动通过header等信息判断编码,不区分HTTP和HTTPS
String result1= HttpUtil.get("https://www.baidu.com");

// 当无法识别页面编码的时候,可以自定义请求页面的编码
String result2= HttpUtil.get("https://www.baidu.com", CharsetUtil.CHARSET_UTF_8);

//可以单独传入http参数,这样参数会自动做URL编码,拼接在URL中
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");

String result3= HttpUtil.get("https://www.baidu.com", paramMap);

Post请求:

HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");

String result= HttpUtil.post("https://www.baidu.com", paramMap);

文件上传:

HashMap<String, Object> paramMap = new HashMap<>();
//文件上传只需将参数中的键指定(默认file),值设为文件对象即可,对于使用者来说,文件上传与普通表单提交并无区别
paramMap.put("file", FileUtil.file("D:\\face.jpg"));

String result= HttpUtil.post("https://www.baidu.com", paramMap);

1.2 使用HttpRequest获得请求状态码
HttpResponse httpResponse = HttpRequest.post(url)
.header(Header.USER_AGENT, "Hutool http")//头信息,多个头信息多次调用此方法即可
.form(paramMap)//表单内容
.timeout(20000)//超时,毫秒
.execute();
int status = httpResponse.getStatus(); //获取响应码
String body = httpResponse.body(); //获取响应内容

2. 请求后的结果类型转换问题
2.1 请求得到的JSON串转对象遇到的cn.hutool.core.convert.ConvertException问题
在工作中向一个第三方的接口请求了一个JSON串,结果在传回的字符串转换成我需要的对象时,显示了如下的报错:

cn.hutool.core.convert.ConvertException: Can not Converter from [cn.hutool.json.JSONObject] to [com.xyc.entity.Student]
at cn.hutool.core.convert.ConverterRegistry.convert(ConverterRegistry.java:280)
at cn.hutool.core.convert.ConverterRegistry.convert(ConverterRegistry.java:295)
at cn.hutool.core.convert.Convert.convertWithCheck(Convert.java:745)

以下为实例代码:

@Test
void jsonToBeanTest(){
// String str = "{\"gender\":\"男\",\"name\":\"李想\",\"id\":1}";
String str = HttpUtil.get(url);
Student student = JSONUtil.toBean(str, Student.class);
System.out.println(student);
}

经排查,原因是因为Student实体类没有get/set方法,补上Lombok的**@Data**注解。问题解决

2.2 请求得到的对象被层层包裹
遇到过一个接口,得到的JSON串类似这样:

{
“msg”: “操作完成”,
“code”: 200,
“data”: {
“result”: {
“root”: [{
“gender”: “男”,
“name”: “李想”,
“id”: 1
}, {
“gender”: “男”,
“name”: “张三”,
“id”: 2
}]
}
}
}

看到的第一眼就头大,还好工具可以很方便的获取节点和对象,实例代码如下:

@Test
void jsonToBeanToList(){
String str = HttpUtil.get(url);
ApiResult apiResult = JSONUtil.toBean(str, ApiResult.class);
if (apiResult != null && apiResult.getCode()==200){
Object resultStr = new JSONObject(apiResult.getData().toString()).get("result");
// 结果: {"root":[{"gender":"男","name":"李想","id":1},{"gender":"男","name":"张三","id":2}]}
JSONArray root = new JSONObject(resultStr.toString()).getJSONArray("root");
List<Student> students = root.toList(Student.class);
}
}

首先根据格式判断是统一响应对象,一般情况下需要判断响应码是否200来进行下一步操作,其中data是我们需要的数据部分。

ApiResult apiResult = JSONUtil.toBean(str, ApiResult.class);

再接着拿出第二层result,这里面还是一个对象,直接通过.get方法获取Object。

root这一层可以发现是一个数组,正好hutool提供了一个JSONArray对象,可以通过JSONArray的toList方法转换成我们需要的List集合。

最终我们需要的对象就在这个List集合当中。