Java实现HTTP请求的几种方式-OKHttp(五)

通过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(四)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值