All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.github.biezhi.wechat.api.client.BotClient Maven / Gradle / Ivy
package io.github.biezhi.wechat.api.client;
import com.google.gson.Gson;
import io.github.biezhi.wechat.api.constant.Constant;
import io.github.biezhi.wechat.api.request.ApiRequest;
import io.github.biezhi.wechat.api.response.ApiResponse;
import io.github.biezhi.wechat.api.response.FileResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* 微信机器人 HTTP 发送端
*
* @author biezhi
* @date 2018/1/18
*/
@Slf4j
public class BotClient {
private final OkHttpClient client;
private OkHttpClient clientWithTimeout;
private final Gson gson;
private static final ConcurrentHashMap> cookieStore = new ConcurrentHashMap>();
public BotClient(OkHttpClient client, Gson gson) {
this.client = client;
this.gson = gson;
System.setProperty("https.protocols", "TLSv1");
System.setProperty("jsse.enableSNIExtension", "false");
}
public void send(final T request, final Callback callback) {
OkHttpClient client = getOkHttpClient(request);
client.newCall(createRequest(request)).enqueue(new okhttp3.Callback() {
@Override
public void onResponse(Call call, Response response) {
try {
String body = response.body().string();
if (log.isDebugEnabled()) {
log.debug("Response: {}", body);
}
if (ApiResponse.class.equals(request.getResponseType())) {
callback.onResponse(request, (R) new ApiResponse(body));
} else {
R result = gson.fromJson(body, request.getResponseType());
result.setRawBody(body);
callback.onResponse(request, result);
}
} catch (Exception e) {
IOException ioEx = e instanceof IOException ? (IOException) e : new IOException(e);
callback.onFailure(request, ioEx);
}
}
@Override
public void onFailure(Call call, IOException e) {
callback.onFailure(request, e);
}
});
}
public R send(final ApiRequest request) {
try {
OkHttpClient client = getOkHttpClient(request);
Request okHttpRequest = createRequest(request);
Response response = client.newCall(okHttpRequest).execute();
String body = response.body().string();
if (log.isDebugEnabled()) {
log.debug("Response : {}", body);
}
// 获取头部的Cookie,注意:可以通过Cooke.parseAll()来获取
List cookies = Cookie.parseAll(okHttpRequest.url(), response.headers());
// 防止header没有Cookie的情况
if (cookies != null && cookies.size() > 0) {
cookieStore.put(okHttpRequest.url().host(), cookies);
if (!"webpush.web.wechat.com".equals(okHttpRequest.url().host())) {
cookieStore.put("webpush.web.wechat.com", cookies);
}
if (!"file.web.wechat.com".equals(okHttpRequest.url().host())) {
cookieStore.put("file.web.wechat.com", cookies);
}
if (!"file.wx2.qq.com".equals(okHttpRequest.url().host())) {
cookieStore.put("file.wx2.qq.com", cookies);
}
}
if (ApiResponse.class.equals(request.getResponseType())) {
return (R) new ApiResponse(body);
}
R result = gson.fromJson(body, request.getResponseType());
result.setRawBody(body);
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public R download(final ApiRequest request) {
try {
OkHttpClient client = getOkHttpClient(request);
Response response = client.newCall(createRequest(request)).execute();
return (R) new FileResponse(response.body().byteStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private OkHttpClient getOkHttpClient(ApiRequest request) {
OkHttpClient client = timeout(request);
if (request.isNoRedirect()) {
return client.newBuilder().followRedirects(false).followSslRedirects(false).build();
}
return cookie(client);
}
/**
* 设置超时
*
* @param request
* @return
*/
private OkHttpClient timeout(ApiRequest request) {
int timeoutMillis = request.getTimeout() * 1000;
if (client.readTimeoutMillis() == 0 || client.readTimeoutMillis() > timeoutMillis) {
return client;
}
if (null != clientWithTimeout && clientWithTimeout.readTimeoutMillis() > timeoutMillis) {
return clientWithTimeout;
}
clientWithTimeout = client.newBuilder().readTimeout(timeoutMillis + 1000, TimeUnit.MILLISECONDS).build();
return clientWithTimeout;
}
private OkHttpClient cookie(OkHttpClient client) {
return client.newBuilder().cookieJar(new CookieJar() {
@Override
public void saveFromResponse(HttpUrl httpUrl, List cookies) {
}
@Override
public List loadForRequest(HttpUrl httpUrl) {
List cookies = cookieStore.get(httpUrl.host());
return cookies != null ? cookies : new ArrayList();
}
}).build();
}
public List cookies() {
List cookies = new ArrayList();
Collection> values = cookieStore.values();
for (List value : values) {
cookies.addAll(value);
}
return cookies;
}
public String cookie(String name) {
for (Cookie cookie : cookies()) {
if (cookie.name().equalsIgnoreCase(name)) {
return cookie.value();
}
}
return null;
}
private Request createRequest(ApiRequest request) {
Request.Builder builder = new Request.Builder();
if (Constant.GET.equalsIgnoreCase(request.getMethod())) {
builder.get();
if (null != request.getParameters() && request.getParameters().size() > 0) {
Set keys = request.getParameters().keySet();
StringBuilder sbuf = new StringBuilder(request.getUrl());
if (request.getUrl().contains("=")) {
sbuf.append("&");
} else {
sbuf.append("?");
}
for (String key : keys) {
sbuf.append(key).append('=').append(request.getParameters().get(key)).append('&');
}
request.url(sbuf.substring(0, sbuf.length() - 1));
}
} else {
builder.method(request.getMethod(), createRequestBody(request));
}
builder.url(request.getUrl());
if (log.isDebugEnabled()) {
log.debug("Request : {}", request.getUrl());
}
if (null != request.getHeaders()) {
builder.headers(request.getHeaders());
}
return builder.build();
}
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private RequestBody createRequestBody(ApiRequest, ?> request) {
if (request.isMultipart()) {
MediaType contentType = MediaType.parse(request.getContentType());
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (Map.Entry parameter : request.getParameters().entrySet()) {
String name = parameter.getKey();
Object value = parameter.getValue();
if (value instanceof byte[]) {
builder.addFormDataPart(name, request.getFileName(), RequestBody.create(contentType, (byte[]) value));
} else if (value instanceof File) {
builder.addFormDataPart(name, request.getFileName(), RequestBody.create(contentType, (File) value));
} else if (value instanceof RequestBody) {
builder.addFormDataPart(name, request.getFileName(), (RequestBody) value);
} else {
builder.addFormDataPart(name, String.valueOf(value));
}
}
return builder.build();
} else {
if (request.isJsonBody()) {
String json = gson.toJson(request.getParameters());
if (log.isDebugEnabled()) {
log.debug("Request Body: {}", json);
}
return RequestBody.create(JSON, json);
} else {
FormBody.Builder builder = new FormBody.Builder();
for (Map.Entry parameter : request.getParameters().entrySet()) {
builder.add(parameter.getKey(), String.valueOf(parameter.getValue()));
}
return builder.build();
}
}
}
}