通过OkHttp进行请求
1. pom文件引入包
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
2. doPost方式请求
请求方法:以下是带参数的例子
/**
* @author zhengbingyuan
* @date 2023/2/1
*/
@Slf4j
@Service
public class OkHttpService {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private final OkHttpClient client;
private final ObjectMapper objectMapper;
private static final int MAX_IDLE_CONNECTION = 5;
//20分钟
private static final long KEEP_ALIVE_DURATION = 20;
//5秒
private static final long CONNECT_TIMEOUT = 5;
//5秒
private static final long READ_TIMEOUT = 5;
public OkHttpService(ObjectMapper objectMapper){
this.client = new OkHttpClient.Builder()
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool(MAX_IDLE_CONNECTION, KEEP_ALIVE_DURATION,
TimeUnit.MINUTES))
.build();
this.objectMapper = objectMapper;
}
/**
*
* @param url
* @param param
* @return
* @throws IOException
*/
public <R> R syncPost(String url, Object param,Class<R> returnType) throws IOException {
String json = null;
if(Objects.nonNull(param)){
json = objectMapper.writeValueAsString(param);
}
//1.创建请求体
RequestBody body = RequestBody.create(JSON, json);
//2.创建请求
Request.Builder builder = new Request.Builder()
.url(url)
.post(body);
//3.附加请求头(可选)
Map<String, Object> headParamsMap = Maps.newHashMap();
String token = getToken();
headParamsMap.put("Authorization", token);
if (!CollectionUtils.isEmpty(headParamsMap)) {
final Iterator<Map.Entry<String, Object>> iterator = headParamsMap.entrySet()
.iterator();
while (iterator.hasNext()) {
final Map.Entry<String, Object> entry = iterator.next();
builder.addHeader(entry.getKey(), (String) entry.getValue());
}
}
Request request = builder.build();
//4.执行请求,得到响应
Response response = this.client.newCall(request).execute();
//5.解析响应
if (response.isSuccessful()) {
String result = response.body().string();
log.info("syncPost response = {}, responseBody= {}", response, result);
R r = objectMapper.readValue(result, returnType);
return r;
}
String result = response.body().string();
log.info("syncPost response = {}, responseBody= {}", response, result);
throw new IOException("三方接口返回http状态码为" + response.code());
}
}
测试程序:
@SneakyThrows
public TestHttpAccessResponse sendHttpRequestByOkHttp(){
TestHttpAccessRequest request = new TestHttpAccessRequest();
request.setAge(16);
request.setName("刘伞");
request.setAddress("佛山市");
String httpUrl = "http://localhost:8082/nacos-service-provider/testHttpAccess";
/**
* 如果是List<T>这种带泛型的对象,则需要使用TypeReference<类型> typeRef = new TypeReference...
* 注意日期的类型,需要事前设置类型转换器
*/
JsonResult jsonResult = okHttpService.syncPost(httpUrl, request, JsonResult.class);
if (Objects.isNull(jsonResult) || !ReturnCode.SUCCESS.getCode().equals(jsonResult.getCode())) {
if (Objects.isNull(jsonResult)) {
throw new BizException(ReturnCode.ERROR);
} else {
throw new BizException(jsonResult.getCode(), jsonResult.getMessage());
}
}
TestHttpAccessResponse response = objectMapper.convertValue(jsonResult.getData(), TestHttpAccessResponse.class);
return response;
}
结果:
{
"code": "40000",
"message": "操作成功",
"data": {
"name": "刘伞",
"age": 16,
"address": "佛山市"
}
}
连接超时演示:
3. doGet方式请求
请求方法:以下是带参数的例子
public <R> R syncGet(String url,Object param,Class<R> returnType) throws IOException, IllegalAccessException {
//1.设置get的参数
if(Objects.nonNull(param)){
//拼接url参数
if(Objects.nonNull(param)){
List<String> params = new ArrayList<>();
Class<?> clazz = param.getClass();
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
Object o = declaredField.get(param);
if (declaredField.getType().equals(String.class)) {
//这里拼接的时候注意要使用URL编码
String s = (String) declaredField.get(param);
s = URLEncoder.encode(s);
o = s;
}
params.add(declaredField.getName() + "=" + o);
}
String paramStr = params.stream().collect(Collectors.joining("&"));
url = url+"?"+paramStr;
}
}
//2.创建请求
Request request;
final Request.Builder builder = new Request.Builder().url(url);
//3.附加请求头(可选)
Map<String, Object> headParamsMap = Maps.newHashMap();
String token = getToken();
headParamsMap.put("Authorization", token);
if (!CollectionUtils.isEmpty(headParamsMap)) {
final Iterator<Map.Entry<String, Object>> iterator = headParamsMap.entrySet()
.iterator();
while (iterator.hasNext()) {
final Map.Entry<String, Object> entry = iterator.next();
builder.addHeader(entry.getKey(), (String) entry.getValue());
}
}
request = builder.build();
//4.执行请求,得到响应
Response response = this.client.newCall(request).execute();
//5.解析响应
if (response.isSuccessful()) {
String result = response.body().string();
log.info("syncGet response = {},responseBody= {}", response, result);
R r = objectMapper.readValue(result, returnType);
return r;
}
String result = response.body().string();
log.info("syncGet response = {}, responseBody= {}", response, result);
throw new IOException("三方接口返回http状态码为" + response.code());
}
测试程序:
@SneakyThrows
public TestHttpAccessResponse sendHttpGetRequestByRestTemplate() {
TestHttpAccessRequest request = new TestHttpAccessRequest();
request.setAge(16);
request.setName("刘伞");
request.setAddress("佛山市");
String httpUrl = "http://localhost:8082/nacos-service-provider/testHttpAccessGet";
/**
* 如果是List<T>这种带泛型的对象,则需要使用TypeReference<类型> typeRef = new TypeReference...
* 注意日期的类型,需要事前设置类型转换器
*/
// JsonResult jsonResult = restTemplateTestService.doGetWith1(httpUrl, request, JsonResult.class);
// JsonResult jsonResult = restTemplateTestService.doGetWith2(httpUrl, request, JsonResult.class);
JsonResult jsonResult = restTemplateTestService.doGetExchange(httpUrl, request, JsonResult.class);
if (Objects.isNull(jsonResult) || !ReturnCode.SUCCESS.getCode().equals(jsonResult.getCode())) {
if (Objects.isNull(jsonResult)) {
throw new BizException(ReturnCode.ERROR);
} else {
throw new BizException(jsonResult.getCode(), jsonResult.getMessage());
}
}
TestHttpAccessResponse response = objectMapper.convertValue(jsonResult.getData(), TestHttpAccessResponse.class);
return response;
}
结果:
{
"code": "40000",
"message": "操作成功",
"data": {
"name": "刘伞",
"age": 16,
"address": "佛山市"
}
}
其他阅读
Java实现HTTP请求的几种方式-HttpURLConnection(一)
Java实现HTTP请求的几种方式-Apache HttpClient(二)
Java实现HTTP请求的几种方式-CloseableHttpClient(三)
Java实现HTTP请求的几种方式-RestTemplate(四)