HttpRemoteUtil远程调用工具
业务场景:
开发时,有时候需要发送http请求到其他项目上,来获取数据,实现业务逻辑。这时就需要弄清楚远程调用怎么实现,需要注意哪些问题。
#code
import cn.iot.api.manage.payment.constant.PaymentConmmonConstants;
import cn.iot.api.manage.payment.vo.BaseResponseVo;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @author xxx
* @Date 2019/4/16 15:14
* @modify 2019/4/16 xxx v2.8.0 创建
* @since v2.8.0
*/
@Configuration
public class PaymentRemoteUtil {
/**
* LOGGER 日志
*/
private static final Logger LOGGER = LoggerFactory.getLogger(PaymentRemoteUtil.class);
public <T> BaseResponseVo<T> doPost(String url, StringEntity body, Map<String, String> header,
TypeReference typeReference) {
// httpClient对象
CloseableHttpClient httpClient = null;
// 返回对象
String resultStr = new String();
BaseResponseVo<T> result = null;
// httpPost对象
HttpPost httpPost = new HttpPost(url);
//设置请求头
if (header != null) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpPost.setHeader(entry.getKey(), entry.getValue());
}
}
try {
//设置请求体
httpPost.setEntity(body);
//发送请求
httpClient = HttpClients.createDefault();
// 发送http请求
HttpResponse response = httpClient.execute(httpPost);
// 从response里拿出返回数据(entity)
HttpEntity entity = response.getEntity();
// 转换成特定编码格式的String
resultStr = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
// 远程调用异常时的处理
LOGGER.info("remote exception ,request url:{},exception is {}", url,e);
} finally {
// 释放连接
httpPost.releaseConnection();
}
//转换成想要的对象
result = JSON.parseObject(resultStr,typeReference.getType());
return result;
}
}
代码说明
1.这个工具类是发送post请求,并且Content-Type为application/json。
2.方法入参body为http请求里的请求体,包含请求体信息(业务参数),body为StringEntity类型,在创建body参数时,一定要先转换成json对象,再创建StringEntity,因为请求头里的参数都是json字符串类型的。另外,需要指定编码格式为远程服务器接口指定的编码格式,否则远程服务器无法解析body里的参数。这两点如果错误,会报400 bad request,建议用以下代码:
StringEntity body = new StringEntity(JSONObject.toJSONString(paymentRequestVo),"UTF-8");
3.方法入参header为http请求的请求头,包含content-type method等信息。方法内部循环将header参数放入httpPost对象。
4.方法入参typeReference为返回数据对象类型。我这里给封装到BaseResponseVo里了,泛型T就是传入的typeReference的类型。除了类型,还支持自己创建的类。调用方法时传入新建的TypeReference 对象即可,建议:
new TypeReference<BaseResponseVo<String>>() {}