@Configuration
public class OkHttpConfig {
/**
* 超时时间,单位(毫秒)
*/
@Value("${okhttp.timeout:7000}")
private Long timeout;
/**
* 最大连接数量
*/
@Value("${okhttp.maxConnection:200}")
private Integer maxConnection;
/**
* 核心连接数量
*/
@Value("${okhttp.coreConnection:10}")
private Integer coreConnection;
/**
* 连接失败是否重试
*/
@Value("${okhttp.resetConnection:false}")
private boolean resetConnection;
/**
* 单域名最大请求线程
*/
@Value("${okhttp.maxHostConnection:30}")
private Integer maxHostConnection;
@Bean
public OkHttpClient okHttpClient() {
// 创建Dispatcher,对请求线程进行控制
Dispatcher dispatcher = new Dispatcher();
// 设置单域名最大连接
dispatcher.setMaxRequestsPerHost(maxHostConnection);
// 设置最大连接
dispatcher.setMaxRequests(maxConnection);
// 创建OkHttpClient连接
return new OkHttpClient
.Builder()
.sslSocketFactory(sslSocketFactory(), x509TrustManager())
.dispatcher(dispatcher)
.retryOnConnectionFailure(resetConnection)
.addInterceptor(new OkHttpInterceptor())
.callTimeout(timeout, TimeUnit.MILLISECONDS)
.connectionPool(new ConnectionPool(maxConnection, coreConnection, TimeUnit.MILLISECONDS))
// 为OkHttp设置自动携带Cookie的功能
.cookieJar(new CookieJar() {
private final Map<String, List<Cookie>> cookieStore = Maps.newHashMap();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
String host = url.host();
List<Cookie> oldCookies = cookieStore.getOrDefault(host, Lists.newArrayList());
// 先移除过期的 Cookie
oldCookies.removeIf(cookie -> cookie.expiresAt() < System.currentTimeMillis());
// key:cookie的名字,value:cookie
Map<String, Cookie> oldMap = oldCookies.stream()
.collect(Collectors.toMap(Cookie::name, Function.identity(), (v1, v2) -> v2));
// 解决 400 Request Header Or Cookie Too Large
if (!CollectionUtils.isEmpty(cookies)) {
// key:cookie的名字,value:cookie
Map<String, Cookie> newMap = cookies.stream()
.collect(Collectors.toMap(Cookie::name, Function.identity(), (v1, v2) -> v2));
// 添加新的 Cookie
oldMap.putAll(newMap);
}
cookieStore.put(host, Lists.newArrayList(oldMap.values()));
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.getOrDefault(url.host(), Lists.newArrayList());
// 移除过期的 Cookie
cookies.removeIf(cookie -> cookie.expiresAt() < System.currentTimeMillis());
return cookies;
}
})
.build();
}
@Bean
public X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
@Bean
public SSLSocketFactory sslSocketFactory() {
try {
// 信任任何链接
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
return null;
}
@Bean
@Primary
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString("");
}
});
return objectMapper;
}
}
@Component
@Slf4j
public class HttpUtils {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private static final MediaType XML = MediaType.parse("application/xml; charset=utf-8");
@Resource
private OkHttpClient okHttpClient;
@Resource
private JsonUtils jsonUtils;
public String get(@NonNull String url) {
return get(url, null, null);
}
public String get(@NonNull String url, Map<String, Object> queryParameter) {
return get(url, queryParameter, null);
}
/**
* 构建http get请求
*
*/
public String get(@NonNull String url, Map<String, Object> queryParameter, Map<String, String> headerParameter) {
Request request = processGetParameter(url, queryParameter, headerParameter);
return execute(request);
}
public String postForm(@NonNull String url) {
return postForm(url, null, null);
}
public String postForm(@NonNull String url, Map<String, Object> queryParameter) {
return postForm(url, queryParameter, null);
}
/**
* 构建http post请求
*
*/
public String postForm(@NonNull String url, Map<String, Object> queryParameter, Map<String, String> headerParameter) {
Request request = processPostFormParameter(url, queryParameter, headerParameter);
return execute(request);
}
public String postJson(@NonNull String url) {
return postJson(url, null, null);
}
public String postJson(@NonNull String url, String dataJson) {
return postJson(url, dataJson, null);
}
/**
* 构建http post json 请求
*
*/
public String postJson(@NonNull String url, String dataJson, Map<String, String> headerParameter) {
Request request = processPostJsonParameter(url, dataJson, headerParameter);
return execute(request);
}
private String execute(Request request) {
try (Response response = okHttpClient.newCall(request).execute()) {
if (response.body() != null) {
return response.body().string();
}
log.warn("==> http response body is null, url:{}", request.url());
return null;
} catch (Exception e) {
log.error("okHttp请求异常,请求地址,{}", request.url(), e);
throw new RuntimeException(e);
}
}
/**
* 构建Json请求
*
*/
private Request processPostJsonParameter(String url, String dataJson, Map<String, String> headerParameter) {
Request.Builder builder = new Request.Builder().url(url);
if (!Objects.isNull(dataJson)) {
RequestBody requestBody = RequestBody.create(JSON, dataJson);
builder.post(requestBody);
} else {
RequestBody requestBody = RequestBody.create(JSON, "{}");
builder.post(requestBody);
}
if (headerParameter != null) {
builder.headers(Headers.of(headerParameter));
}
return builder.build();
}
/**
* 构建Post请求
*
*/
private Request processPostFormParameter(String url, Map<String, Object> parameters, Map<String, String> headerParameter) {
Request.Builder builder = new Request.Builder().url(url);
if (headerParameter != null) {
builder.headers(Headers.of(headerParameter));
}
if (parameters != null) {
FormBody.Builder formBuilder = new FormBody.Builder();
parameters.forEach((k, v) -> formBuilder.add(k, String.valueOf(v)));
builder.post(formBuilder.build());
}
return builder.build();
}
/**
* 构建Get请求
*
*/
private Request processGetParameter(String url, Map<String, Object> queryParameter, Map<String, String> headerParameter) {
Request.Builder builder = new Request.Builder();
StringBuilder sb = new StringBuilder(url);
if (headerParameter != null) {
builder.headers(Headers.of(headerParameter));
}
if (queryParameter != null) {
boolean firstFlag = true;
for (String key : queryParameter.keySet()) {
if (firstFlag) {
sb.append("?").append(key).append("=").append(queryParameter.get(key));
firstFlag = false;
} else {
sb.append("&").append(key).append("=").append(queryParameter.get(key));
}
}
}
return builder.url(sb.toString()).build();
}
@Slf4j
@Component
public class JsonUtils {
@Resource
private ObjectMapper objectMapper;
/**
* 转字符串
*
*/
public String toString(Object o) {
try {
if (o != null) {
return objectMapper.writeValueAsString(o);
}
} catch (Exception e) {
log.error("==> toString error", e);
}
return null;
}
/**
* 字符串转对象
*
*/
public <T> T toObject(String json, Class<T> valueType) {
try {
return StringUtils.isNotBlank(json) && !CommonConstant.STRING_NULL.equalsIgnoreCase(json) ?
objectMapper.readValue(json, valueType) : null;
} catch (Exception e) {
log.error("==> toObject error", e);
}
return null;
}
/**
* 字符串转数组
*
*/
public <T> T[] toArray(String json, Class<T> valueType) {
try {
if (StringUtils.isNotBlank(json) && !CommonConstant.STRING_NULL.equalsIgnoreCase(json)) {
ArrayType arrayType = objectMapper.getTypeFactory().constructArrayType(valueType);
return objectMapper.readValue(json, arrayType);
}
} catch (Exception e) {
log.error("==> toArray error", e);
}
return null;
}
/**
* 字符串转集合
*
*/
public <T> List<T> toList(String json, Class<T> valueType) {
List<T> list = Lists.newArrayList();
try {
if (StringUtils.isNotBlank(json) && !CommonConstant.STRING_NULL.equalsIgnoreCase(json)) {
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, valueType);
List<T> value = objectMapper.readValue(json, listType);
if (CollectionUtils.isNotEmpty(value)) {
list.addAll(value);
}
}
} catch (Exception e) {
log.error("==> toList error", e);
}
return list;
}
/**
* 字符串转JsonNode 可操作性高
*
*/
public JsonNode toJsonNode(String json) {
try {
return StringUtils.isNotBlank(json) && !CommonConstant.STRING_NULL.equalsIgnoreCase(json) ?
objectMapper.readTree(json) : null;
} catch (Exception e) {
log.error("==> toJsonNode error", e);
}
return null;
}
/**
* 转对象
*
*/
public <T> T toObject(JsonNode jsonNode, Class<T> valueType) {
try {
return toObject(toString(jsonNode), valueType);
} catch (Exception e) {
log.error("==> toObject error", e);
}
return null;
}
public JsonNode getJsonNode(JsonNode jsonNode, String fieldName) {
if (jsonNode != null && jsonNode.has(fieldName)) {
return jsonNode.get(fieldName);
}
return null;
}
public String getString(JsonNode jsonNode, String fieldName) {
if (jsonNode != null && jsonNode.has(fieldName)) {
String result = StringUtils.trimToNull(jsonNode.get(fieldName).asText());
return CommonConstant.STRING_NULL.equalsIgnoreCase(result) ? null : result;
}
return null;
}
public int getInt(JsonNode jsonNode, String fieldName) {
if (jsonNode != null && jsonNode.has(fieldName)) {
return jsonNode.get(fieldName).intValue();
}
return 0;
}
}