新版改版:
新增B站接口 测试直播WebSocket
This commit is contained in:
11
common/src/main/java/com/yutou/okhttp/FileBody.java
Normal file
11
common/src/main/java/com/yutou/okhttp/FileBody.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.yutou.okhttp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@Data
|
||||
public class FileBody<T> {
|
||||
InputStream inputStream;
|
||||
T t;
|
||||
}
|
||||
103
common/src/main/java/com/yutou/okhttp/FileCallback.java
Normal file
103
common/src/main/java/com/yutou/okhttp/FileCallback.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package com.yutou.okhttp;
|
||||
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.HttpUrl;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class FileCallback<T> implements Callback<FileBody<T>> {
|
||||
|
||||
private static ThreadPoolExecutor executor;
|
||||
private final T bean;
|
||||
|
||||
|
||||
public FileCallback(T bean) {
|
||||
this.bean = bean;
|
||||
if (executor == null) {
|
||||
executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
|
||||
}
|
||||
}
|
||||
|
||||
private class DownloadTask implements Runnable {
|
||||
private T bean;
|
||||
private Headers headers;
|
||||
private HttpUrl url;
|
||||
private InputStream inputStream;
|
||||
|
||||
public DownloadTask(T bean, Headers headers, HttpUrl url, InputStream inputStream) {
|
||||
this.bean = bean;
|
||||
|
||||
this.headers = headers;
|
||||
this.url = url;
|
||||
this.inputStream = inputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
System.out.println("开始下载");
|
||||
File file = new File("download" + File.separator + System.currentTimeMillis() + ".flv");
|
||||
onStart(bean);
|
||||
if (!file.exists()) {
|
||||
boolean mkdirs = file.getParentFile().mkdirs();
|
||||
System.out.println("mkdirs = " + mkdirs);
|
||||
}
|
||||
FileOutputStream outputStream = new FileOutputStream(file);
|
||||
int len;
|
||||
long total = 0;
|
||||
byte[] bytes = new byte[4096];
|
||||
boolean isDownload = true;
|
||||
long available = inputStream.available();
|
||||
while ((len = inputStream.read(bytes)) != -1 && isDownload) {
|
||||
total += len;
|
||||
outputStream.write(bytes, 0, len);
|
||||
outputStream.flush();
|
||||
isDownload = onDownload(headers, bean, total, available);
|
||||
}
|
||||
System.out.println("下载完成");
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
onFinish(bean);
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract void onStart(T bean);
|
||||
|
||||
public abstract boolean onDownload(Headers headers, T bean, long len, long total);
|
||||
|
||||
public abstract void onFinish(T bean);
|
||||
|
||||
public abstract void onFailure(T bean, Throwable throwable);
|
||||
|
||||
@Override
|
||||
public void onResponse(Call<FileBody<T>> call, Response<FileBody<T>> response) {
|
||||
executor.execute(new DownloadTask(bean, response.headers(), call.request().url(), response.body().getInputStream()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<FileBody<T>> call, Throwable throwable) {
|
||||
onFailure(bean, throwable);
|
||||
call.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,6 +38,7 @@ public class ParamsContext {
|
||||
break;
|
||||
}
|
||||
headerMap.remove("tableName");
|
||||
headerMap.put("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36");
|
||||
return iRequestParam.getRequest(headerMap, map, request);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.yutou.okhttp.api;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.internal.bind.DateTypeAdapter;
|
||||
@@ -7,10 +8,7 @@ import com.yutou.okhttp.HttpLoggingInterceptor;
|
||||
import com.yutou.okhttp.ParamsContext;
|
||||
import com.yutou.okhttp.converter.JsonCallAdapter;
|
||||
import com.yutou.okhttp.converter.JsonConverterFactory;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.*;
|
||||
import retrofit2.CallAdapter;
|
||||
import retrofit2.Converter;
|
||||
import retrofit2.Retrofit;
|
||||
@@ -21,8 +19,8 @@ import java.util.HashMap;
|
||||
|
||||
public class BaseApi {
|
||||
private String URL;
|
||||
private HashMap<String, String> params;
|
||||
private HashMap<String, String> headers;
|
||||
private HashMap<String, String> params = new HashMap<>();
|
||||
private HashMap<String, String> headers = new HashMap<>();
|
||||
|
||||
public BaseApi(String URL) {
|
||||
this.URL = URL;
|
||||
@@ -42,16 +40,24 @@ public class BaseApi {
|
||||
this.params = params;
|
||||
return this;
|
||||
}
|
||||
public void useCookie(JSONObject json){
|
||||
StringBuilder ck = new StringBuilder();
|
||||
for (String key : json.keySet()) {
|
||||
ck.append(key).append("=").append(json.getString(key)).append("; ");
|
||||
}
|
||||
headers.put("Cookie", ck.toString());
|
||||
setHeaders(headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个接口方法
|
||||
*
|
||||
* @param okHttpClient okhttp客户端
|
||||
* @param converterFactory 处理工厂类
|
||||
* @param okHttpClient okhttp客户端
|
||||
* @param converterFactory 处理工厂类
|
||||
* @param callAdapterFactory 请求适配器工厂
|
||||
* @param baseUrl 基础地质
|
||||
* @param service 接口
|
||||
* @param <T> 接口泛型
|
||||
* @param baseUrl 基础地质
|
||||
* @param service 接口
|
||||
* @param <T> 接口泛型
|
||||
* @return 接口
|
||||
*/
|
||||
public <T> T create(OkHttpClient okHttpClient, Converter.Factory converterFactory, CallAdapter.Factory callAdapterFactory, String baseUrl, Class<T> service) {
|
||||
@@ -92,13 +98,14 @@ public class BaseApi {
|
||||
URL,
|
||||
apiClass);
|
||||
}
|
||||
|
||||
public Interceptor initQuery() {
|
||||
Interceptor addQueryParameterInterceptor = new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
//配置公共参数
|
||||
request = new ParamsContext(headers,params,request).getInRequest();
|
||||
request = new ParamsContext(headers, params, request).getInRequest();
|
||||
return chain.proceed(request);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,9 +2,9 @@ package com.yutou.okhttp.converter;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.alibaba.fastjson2.JSONReader;
|
||||
import com.alibaba.fastjson2.JSONWriter;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.yutou.okhttp.FileBody;
|
||||
import com.yutou.okhttp.HttpBody;
|
||||
import okhttp3.ResponseBody;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -27,19 +27,25 @@ public class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T>
|
||||
@Nullable
|
||||
@Override
|
||||
public T convert(ResponseBody responseBody) throws IOException {
|
||||
String string = new String(responseBody.bytes());
|
||||
responseBody.close();
|
||||
HttpBody<T> body;
|
||||
try {
|
||||
body = JSONObject.parseObject(string, type, JSONReader.Feature.FieldBased);
|
||||
body.setSrc(string);
|
||||
if (type.getTypeName().contains(HttpBody.class.getSimpleName())) {
|
||||
String string = new String(responseBody.bytes());
|
||||
responseBody.close();
|
||||
HttpBody<T> body;
|
||||
try {
|
||||
body = JSONObject.parseObject(string, type, JSONReader.Feature.FieldBased);
|
||||
body.setSrc(string);
|
||||
return (T) body;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
body = new HttpBody();
|
||||
body.setSrc(string);
|
||||
}
|
||||
return (T) body;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
body = new HttpBody();
|
||||
body.setSrc(string);
|
||||
}
|
||||
return (T) body;
|
||||
|
||||
} else {
|
||||
FileBody<T> body=new FileBody<T>();
|
||||
body.setInputStream(responseBody.byteStream());
|
||||
return (T) body;
|
||||
}
|
||||
}
|
||||
}
|
||||
136
common/src/main/java/com/yutou/utils/RSAUtils.java
Normal file
136
common/src/main/java/com/yutou/utils/RSAUtils.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package com.yutou.utils;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.*;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RSAUtils {
|
||||
/**
|
||||
* 加密算法RSA
|
||||
*/
|
||||
public static final String KEY_ALGORITHM = "RSA";
|
||||
|
||||
/**
|
||||
* 签名算法
|
||||
*/
|
||||
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
|
||||
|
||||
/**
|
||||
* 获取公钥的key
|
||||
*/
|
||||
private static final String PUBLIC_KEY = "RSAPublicKey";
|
||||
|
||||
/**
|
||||
* 获取私钥的key
|
||||
*/
|
||||
private static final String PRIVATE_KEY = "RSAPrivateKey";
|
||||
|
||||
/**
|
||||
* RSA 密钥位数
|
||||
*/
|
||||
private static final int KEY_SIZE = 1024;
|
||||
|
||||
/**
|
||||
* RSA最大解密密文大小
|
||||
*/
|
||||
private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;
|
||||
|
||||
/**
|
||||
* RSA最大加密明文大小
|
||||
*/
|
||||
private static final int MAX_ENCRYPT_BLOCK = MAX_DECRYPT_BLOCK - 11;
|
||||
private static Map<Integer,String> keyMap=new HashMap<>();
|
||||
|
||||
/**
|
||||
* 随机生成密钥对
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static void getKeyPair() throws Exception {
|
||||
//KeyPairGenerator类用于生成公钥和密钥对,基于RSA算法生成对象
|
||||
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
|
||||
//初始化密钥对生成器,密钥大小为96-1024位
|
||||
keyPairGen.initialize(1024,new SecureRandom());
|
||||
//生成一个密钥对,保存在keyPair中
|
||||
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||||
PrivateKey privateKey = keyPair.getPrivate();//得到私钥
|
||||
PublicKey publicKey = keyPair.getPublic();//得到公钥
|
||||
//得到公钥字符串
|
||||
String publicKeyString=new String(Base64.encodeBase64(publicKey.getEncoded()));
|
||||
//得到私钥字符串
|
||||
String privateKeyString=new String(Base64.encodeBase64(privateKey.getEncoded()));
|
||||
//将公钥和私钥保存到Map
|
||||
keyMap.put(0,publicKeyString);//0表示公钥
|
||||
keyMap.put(1,privateKeyString);//1表示私钥
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* 公钥加密
|
||||
* </p>
|
||||
*
|
||||
* @param str 源数据
|
||||
* @param publicKey 公钥(BASE64编码)
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encryptByPublicKey(String str, String publicKey) throws Exception {
|
||||
publicKey=publicKey.replace("-----BEGIN PUBLIC KEY-----","").replace("-----END PUBLIC KEY-----","");
|
||||
byte[] data=Base64.decodeBase64(str);
|
||||
byte[] keyBytes = Base64.decodeBase64(publicKey);
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||||
// 对数据加密
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicK);
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段加密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
byte[] encryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return new String(Base64.encodeBase64(encryptedData));
|
||||
}
|
||||
|
||||
/**
|
||||
* RSA私钥解密
|
||||
*
|
||||
* @param str
|
||||
* 加密字符串
|
||||
* @param privateKey
|
||||
* 私钥
|
||||
* @return 铭文
|
||||
* @throws Exception
|
||||
* 解密过程中的异常信息
|
||||
*/
|
||||
public static String decrypt(String str,String privateKey) throws Exception {
|
||||
//Base64解码加密后的字符串
|
||||
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
|
||||
//Base64编码的私钥
|
||||
byte[] decoded = Base64.decodeBase64(privateKey);
|
||||
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
|
||||
//RSA解密
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE,priKey);
|
||||
String outStr=new String(cipher.doFinal(inputByte));
|
||||
return outStr;
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user