springboot装配OkHttp组件

在SpringBoot应用中,发送Http通常我们使用RestTemplate,但有部分组件底层是使用OkHttp进行Http的操作,而且OKHttp也是一个很优秀的HTTP组件。

RestTempate的springboot封装参考:https://www.cnblogs.com/yangzhilong/p/6640207.html

application.yml

okhttp:
  connect-timeout-ms: 500
  keep-alive-duration-sec: 5000
  max-idle: 100
  read-timeout-ms: 500
  write-timeout-ms: 500

Configuration:

import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import com.longge.gateway.util.OkHttpUtils;

import lombok.Getter;
import lombok.Setter;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;

/**
 * @author roger yang
 * @date 9/16/2019
 */
public class OkHttpConfiguration {
    @Resource
    private OkHttpConfig okHttpConfig;
    
    @Bean
    public OkHttpClient okHttpClient() {
        OkHttpClient client = new OkHttpClient.Builder()
                .retryOnConnectionFailure(false)
                .connectionPool(pool())
                .connectTimeout(okHttpConfig.getConnectTimeoutMs(), TimeUnit.MILLISECONDS)
                .readTimeout(okHttpConfig.getReadTimeoutMs(), TimeUnit.MILLISECONDS)
                .writeTimeout(okHttpConfig.getWriteTimeoutMs(),TimeUnit.MILLISECONDS)
                .build();
        
        OkHttpUtils.setOkHttpClient(client);
        return client;
    }
    
    @Bean
    public ConnectionPool pool() {
        return new ConnectionPool(okHttpConfig.getMaxIdle(), okHttpConfig.getKeepAliveDurationSec(), TimeUnit.SECONDS);
    }
    
    @Component
    @ConfigurationProperties(prefix = "okhttp")
    @Getter
    @Setter
    @Validated
    static class OkHttpConfig {
        @NotNull
        private Long connectTimeoutMs;
        @NotNull
        private Long readTimeoutMs;
        @NotNull
        private Long writeTimeoutMs;
        @NotNull
        private Integer maxIdle;
        @NotNull
        private Long keepAliveDurationSec;
    }
}

 

Util帮助类:

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Objects;

import com.alibaba.fastjson.JSONObject;

import lombok.NonNull;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 参数中Callback表示发送异步请求
 * @author roger yang
 * @date 9/16/2019
 */
public class OkHttpUtils {
    private static OkHttpClient okHttpClient;

    public static void setOkHttpClient(OkHttpClient client) {
        okHttpClient = client;
    }
    
    /**
     * GET Method begin---------------------------------
     */
    
    public static <T> T get(@NonNull String url, Class<T> clasz) {
        return get(url, null, null, clasz);
    }
    
    public static void get(@NonNull String url, Callback callback) {
        get(url, null, null, callback);
    }

    public static <T> T get(@NonNull String url, Map<String, String> queryParameter, Class<T> clasz) {
        return get(url, null, queryParameter, clasz);
    }
    
    public static void get(@NonNull String url, Map<String, String> queryParameter, Callback callback) {
        get(url, null, queryParameter, callback);
    }

    public static <T> T get(@NonNull String url, Map<String, String> headerParameter, Map<String, String> queryParameter, Class<T> clasz) {
        Request request = processGetParameter(url, headerParameter, queryParameter);

        try (Response resp = okHttpClient.newCall(request).execute();) {
            return processResponse(resp, clasz);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    public static void get(@NonNull String url, Map<String, String> headerParameter, Map<String, String> queryParameter, Callback callback) {
        Request request = processGetParameter(url, headerParameter, queryParameter);
        okHttpClient.newCall(request).enqueue(callback);
    }
    
    private static Request processGetParameter(String url, Map<String, String> headerParameter, Map<String, String> queryParameter) {
        Request.Builder builder = new Request.Builder();
        if (!isEmptyMap(headerParameter)) {
            builder.headers(Headers.of(headerParameter));
        }
        if (isEmptyMap(queryParameter)) {
            builder.url(url);
        } else {
            boolean hasQuery = false;
            try {
                hasQuery = new URL(url).getQuery().isEmpty();
            } catch (MalformedURLException e) {
                throw new RuntimeException("url is illegal");
            }
            StringBuilder sb = new StringBuilder(url);
            if (!hasQuery) {
                sb.append("?1=1");
            }
            queryParameter.forEach((k, v) -> {
                sb.append("&").append(k).append("=").append(v);
            });
            builder.url(sb.toString());
        }
        return builder.build();
    }

    /**
     * POST Method With JSON begin---------------------------------
     */
    
    public static <T> T postJson(@NonNull String url, Class<T> clasz) {
        return postJson(url, null, null, clasz);
    }
    
    public static void postJson(@NonNull String url, Callback callback) {
        postJson(url, null, null, callback);
    }

    public static <T> T postJson(@NonNull String url, Map<String, String> headerParameter, Class<T> clasz) {
        return postJson(url, headerParameter, null, clasz);
    }
    
    public static void postJson(@NonNull String url, Map<String, String> headerParameter, Callback callback) {
        postJson(url, headerParameter, null, callback);
    }
    
    public static <T> T postJson(@NonNull String url, Map<String, String> headerParameter, Object bodyObj, Class<T> clasz) {
        Request request = processPostJsonParameter(url, headerParameter, bodyObj);
        try (Response resp = okHttpClient.newCall(request).execute();) {
            return processResponse(resp, clasz);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static void postJson(@NonNull String url, Map<String, String> headerParameter, Object bodyObj, Callback callback) {
        Request request = processPostJsonParameter(url, headerParameter, bodyObj);
        okHttpClient.newCall(request).enqueue(callback);
    }
    
    private static Request processPostJsonParameter(String url, Map<String, String> headerParameter, Object bodyObj) {
        Request.Builder builder = new Request.Builder().url(url);
        if(!Objects.isNull(bodyObj)) {
            RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSONObject.toJSONString(bodyObj));
            builder.post(body);
        } else {
            RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), "{}");
            builder.post(body);
        }
        if (!isEmptyMap(headerParameter)) {
            builder.headers(Headers.of(headerParameter));
        }
        return builder.build();
    }
    
    /**
     * POST Method With Form begin---------------------------------
     */
    
    public static <T> T postForm(@NonNull String url, Class<T> clasz) {
        return postForm(url, null, null, clasz);
    }
    
    public static void postForm(@NonNull String url, Callback callback) {
        postForm(url, null, null, callback);
    }

    public static <T> T postForm(@NonNull String url, Map<String, String> headerParameter, Class<T> clasz) {
        return postForm(url, headerParameter, null, clasz);
    }
    
    public static void postForm(@NonNull String url, Map<String, String> headerParameter, Callback callback) {
        postForm(url, headerParameter, null, callback);
    }
    
    public static <T> T postForm(@NonNull String url, Map<String, String> headerParameter, Map<String, String> parameters, Class<T> clasz) {
        Request request = processPostFormParameter(url, headerParameter, parameters);
        try (Response resp = okHttpClient.newCall(request).execute();) {
            return processResponse(resp, clasz);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static void postForm(@NonNull String url, Map<String, String> headerParameter, Map<String, String> parameters, Callback callback) {
        Request request = processPostFormParameter(url, headerParameter, parameters);
        okHttpClient.newCall(request).enqueue(callback);
    }
    
    private static Request processPostFormParameter(String url, Map<String, String> headerParameter, Map<String, String> parameters) {
        Request.Builder builder = new Request.Builder().url(url);
        if(!Objects.isNull(parameters)) {
            FormBody.Builder formBuilder = new FormBody.Builder();
            parameters.forEach((k, v) -> {
                formBuilder.add(k, v);
            });
            builder.post(formBuilder.build());
        }
        if (!isEmptyMap(headerParameter)) {
            builder.headers(Headers.of(headerParameter));
        }
        return builder.build();
    }
    
    @SuppressWarnings("unchecked")
    private static <T> T processResponse(Response resp, Class<T> clasz) throws IOException {
        if (resp.isSuccessful()) {
            if (Objects.equals(Void.class, clasz)) {
                return null;
            }
            String respStr = resp.body().string();
            if(Objects.equals(String.class, clasz)) {
                return (T)respStr;
            }
            return JSONObject.parseObject(respStr, clasz);
        }
        return null;
    }
    
    private static boolean isEmptyMap(Map<? extends Object, ? extends Object> map) {
        return Objects.isNull(map) || map.isEmpty();
    }
}

GitHub地址:https://github.com/yangzhilong/new-gateway-test.git

如果想要OkHttp的装配是非自动的,可以采用自定义@EnableXX注解来实现。

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.context.annotation.Import;

import com.longge.gateway.configuration.OkHttpConfiguration;

/**
 * @author roger yang
 * @date 9/16/2019
 */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Import(OkHttpConfiguration.class)
public @interface EnableOkHttp {

}

然后把OkHttpConfiguration类的@Configuration注解去掉,当你要用时在启动类加上@EnableOkHttp即可。

posted @ 2019-09-16 15:29  自行车上的程序员  阅读(6375)  评论(0编辑  收藏  举报