
com.jladder.net.http.HttpHelper Maven / Gradle / Ivy
package com.jladder.net.http;
import com.jladder.data.Receipt;
import com.jladder.data.Record;
import com.jladder.data.UploadFile;
import com.jladder.lang.*;
import com.jladder.lang.func.Action1;
import com.jladder.lang.func.Action2;
import com.jladder.web.WebContext;
import jakarta.servlet.http.HttpServletRequest;
import okhttp3.*;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class HttpHelper{
private static final OkHttpClient OkClient = setSSL(new OkHttpClient.Builder()
.connectTimeout(60 , TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.MINUTES)
.writeTimeout(5, TimeUnit.MINUTES))
//.hostnameVerifier(new TrustAllHostnameVerifier())//trust all?信任所有host
.build();
// private static final OkHttpClient OkClient = null;
private static final MediaType URLENCODED = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
private static final MediaType JSON = MediaType.parse("application/json;charset=utf-8");
private static final MediaType MutilPart_Form_Data = MediaType.parse("multipart/form-data; charset=utf-8");
/**
* 获取OkHttpClient实例,设置连接超时时间、读取超时时间和写入超时时间
*
* @param time 读取超时时间和写入超时时间,单位为秒
* @return OkHttpClient实例
*/
private static OkHttpClient getOkClient(int time){
OkHttpClient client = setSSL(new OkHttpClient.Builder()
.connectTimeout(60 , TimeUnit.SECONDS)
.readTimeout(time, TimeUnit.SECONDS)
.writeTimeout(time, TimeUnit.SECONDS))
//.hostnameVerifier(new TrustAllHostnameVerifier())//trust all?信任所有host
.build();
return client;
}
/**
* 获取客户端IP
* @return 当前请求的Ip
*/
public static String getIp(){
return getIp(WebContext.getRequest());
}
/**
* 获取客户端IP
* @param request 请求头
* @return 客户端IP
*/
public static String getIp(HttpServletRequest request) {
try{
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}catch (Exception e){
return "127.0.0.1";
}
}
public static String toFormData(Object data) {
return toFormData(data, false);
}
/**
* 转为formdata数据 a=1&b=3
* @param data 源数据
* @param encoding 是否URL编码
* @return 客户端IP
*/
public static String toFormData(Object data, boolean encoding) {
final String[] postData = {""};
boolean ok = false;
if (data instanceof String) {
ok = true;
String poststr = data.toString().trim();
if (Strings.isJson(poststr, 1)) {
Record record = Record.parse(poststr);
if (record != null) {
record.forEach((k, v) -> postData[0] += k + "=" + (encoding ? encode(v.toString()) : v) + "&");
}
postData[0] = Strings.rightLess(postData[0], 1);
} else {
postData[0] = poststr;
}
}
if (ok) return postData[0];
{
Record record = Record.parse(data);
if (record != null) {
record.forEach((k, v) -> postData[0] += k + "=" + (encoding ? encode(v==null?"":v.toString()) : v) + "&");
}
postData[0] = Strings.rightLess(postData[0], 1);
}
return postData[0];
}
/**
* 编码数据
* @param data 数据
* @return 编码数据
*/
public static String encode(String data) {
try {
return URLEncoder.encode(data,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "";
}
}
/**
* 解码数据
* @param data 数据
* @return 解码数据
*/
public static String decode(String data) {
try {
return URLDecoder.decode(data,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "";
}
}
/**
* 以PostJson方式请求
* @param url 请求地址
* @param data 请求数据
* @param header 请求头
* @param method 请求方式
*/
public static Receipt requestByJson(String url, Object data, Record header, String method){
return requestByJson(url,data,header,null,null,method);
}
/**
* 以PostJson方式请求
* @param url 请求地址
* @param data 请求数据
* @param header 请求头
*/
public static Receipt requestByJson(String url, Object data, Record header){
return requestByJson(url,data,header,null,null,"post");
}
/**
* 以PostJson方式请求
* @param url 请求地址
* @param data 请求数据
* @param header 请求头
* @param onRequest 请求处理
* @param onResponse 回复处理
*/
public static Receipt requestByJson(String url, Object data, Record header, Action1 onRequest, Action2 onResponse){
return requestByJson(url,data,header,onRequest,onResponse,"post");
}
/**
* 以PostJson方式请求
* @param url 请求地址
* @param data 请求数据
* @param header 请求头
* @param method 请求方式
* @param onRequest 请求处理
* @param onResponse 回复处理
*/
public static Receipt requestByJson(String url, Object data, Record header, Action1 onRequest, Action2 onResponse, String method) {
Response response = null;
try {
Request.Builder request = new Request.Builder().url(url);
if(Strings.isBlank(method))method="post";
RequestBody json = null;
if (data != null) {
if (data instanceof String) {
json= createRequestBody(data.toString(),JSON);
} else {
json= createRequestBody(Json.toJson(data),JSON);
}
}
switch (method.toLowerCase()){
case "post":
request.post(json);
break;
case "put":
request.put(json);
break;
case "delete":
request.delete(json);
break;
default:
request.get();
break;
}
//request.head().addHeader("Content-Type","application/json");
if (header != null && header.size() > 0) {
header.forEach((k, v) -> {
if (Regex.isMatch(k, "(accept)|(connection)|(content-length)|(content-type)|(host)|(expect)|(if-modified-since)|(accept-encoding)"))
return;
String value = v.toString();
//value = encode(value);//处理中文
//以_name_形式,为Ladder类库增加
if (Regex.isMatch(k, "_(\\w*)_")) {
request.header(k, Json.toJson(value));
return;
}
switch (k.toLowerCase()) {
// case "user-agent":
// //request.UserAgent = UrlEncode(x.Value.ToString());
// break;
// case "referer":
// case "if-modified-since":
// request.referer = value;
// break;
// case "cookie":
// break;
// if (cookies.IsBlank()) request.Headers.Add("Cookie", value);
// break;
// case "accept-encoding":
// break;
// case "x-forwarded-for":
// break;
default:
request.header(k, Json.toJson(value));
break;
}
//request.header(k,v==null?"":v.toString());
});
}
if(onRequest!=null)onRequest.invoke(request);
Call call = OkClient.newCall(request.build());
response = repair(call.execute(),request);
String text = response.body().string();
if(onResponse!=null)onResponse.invoke(text,response);
if (response.isSuccessful()) {
return new Receipt(true).setData(text);
}else{
return new Receipt(false).setData(response.code()+"["+text+"]");
}
} catch (Exception e) {
System.out.println("ladder-httperror:"+(response!=null?"["+response.code()+"]":"")+url+","+e.getMessage());
return new Receipt(false,e.getMessage()).setData(e.toString());
}
}
/**
* 网络请求,以POST方式
* @param url 服务地址
* @param data 请求数据
*/
public static Receipt request(String url, Object data){
return request(url,data,"POST",null);
}
/**
* 网络请求
* @param url 服务地址
* @param data 请求数据
* @param method 请求方式
*/
public static Receipt request(String url, Object data, String method){return request(url,data,method,null);}
private static RequestBody createRequestBody(String bodyString,MediaType type){
return RequestBody.create(type,bodyString);
}
/**
* 创建RequestBody对象
*
* @param data 字节数组,用于存储请求体数据
* @param type MediaType类型,用于指定请求体的MIME类型
* @return 返回创建的RequestBody对象
*/
private static RequestBody createRequestBody(byte[] data,MediaType type){
return RequestBody.create(type,data);
}
/**
* 发送HTTP请求。
*
* @param url 请求的URL地址。
* @param data 请求的数据。
* @param method 请求的方法,如GET、POST等。
* @param header 请求头信息。
* @return 回复文本数据
*/
public static Receipt request(String url, Object data, String method, Record header){
return request(url,data,method,header,-1,null);
}
/**
* 发送HTTP请求
*
* @param url 请求地址
* @param data 请求参数
* @param method 请求方法,支持GET、POST、PUT、DELETE等
* @param header 请求头信息
* @param second 超时时间,单位为秒
* @return 回复文本数据
*/
public static Receipt request(String url, Object data, String method, Record header,int second){
return request(url,data,method,header,second,null);
}
/**
* 网络请求
*
* @param url 服务地址
* @param data 请求数据
* @param method 请求方式
* @param header 请求头
* @param second 超时时间,单位为秒
* @return 返回一个Receipt对象,包含请求是否成功及返回的数据
*/
public static Receipt request(String url, Object data, String method, Record header,int second,Action1 onResponse) {
if(Strings.isBlank(url))return new Receipt(false,"访问地址未填写");
if (Strings.isBlank(method)) method = "post";
Response response = null;
try {
Request.Builder request = null;
if(false && "post".equalsIgnoreCase(method) && data instanceof Record){
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
if(data!=null){
((Record)data).forEach((k,v)->{
if(v!=null)
requestBodyBuilder.addFormDataPart(k,v.toString());
});
}
MultipartBody requestBody = requestBodyBuilder.build();
request = new Request.Builder().url(url).post(requestBody);
}else{
String bodyString = toFormData(data, true);
// if(url.startsWith("${host}")){
// url.replace("${host}",WebContext.getHost());
// }
request = new Request.Builder().url(url);
switch (method.toLowerCase()) {
case "post":
request.post(createRequestBody(bodyString, URLENCODED));
break;
case "put":
request.put(createRequestBody(bodyString, URLENCODED));
break;
case "delete":
request.delete(createRequestBody(bodyString, URLENCODED));
break;
default:
request.url(url + (url.contains("?") ? "&" + bodyString : "?" + bodyString)).get();
break;
}
}
if (header != null && header.size() > 0) {
Request.Builder finalRequest = request;
header.forEach((k, v) -> {
if (Regex.isMatch(k, "(accept)|(connection)|(content-length)|(content-type)|(host)|(expect)|(if-modified-since)|(accept-encoding)"))
return;
if(v==null)return;
String value = v.toString();
//value = encode(value);//处理中文
//以_name_形式,为Ladder类库增加
if (Regex.isMatch(k, "_(\\w*)_")) {
finalRequest.header(k, Json.toJson(value));
return;
}
switch (k.toLowerCase()) {
// case "user-agent":
// //request.UserAgent = UrlEncode(x.Value.ToString());
// break;
// case "referer":
// case "if-modified-since":
// request.referer = value;
// break;
// case "cookie":
// break;
// if (cookies.IsBlank()) request.Headers.Add("Cookie", value);
// break;
// case "accept-encoding":
// break;
// case "x-forwarded-for":
// break;
default:
finalRequest.header(k, Json.toJson(value));
break;
}
//request.header(k,v==null?"":v.toString());
});
}
//创建"调用" 对象
OkHttpClient client = second < 1 ? OkClient : getOkClient(second);
Call call = client.newCall(request.build());
response = repair(call.execute(),request);//执行
if(onResponse!=null)onResponse.invoke(response);
if (response.isSuccessful()) {
return new Receipt(true).setData(response.body().string());
//System.out.println(response.body().string());
}else{
return new Receipt(false).setData(response.body().string());
}
} catch (Exception e) {
System.out.println("ladder-httperror:"+(response!=null?"["+response.code()+"]":"")+url+","+e.getMessage());
if(onResponse!=null && response!=null) {
try {
onResponse.invoke(response);
} catch (Exception ex) {
ex.printStackTrace();
}
}
return new Receipt(false,e.getMessage()).setData(e.toString());
}
}
/**
* 修复回复头
* @param response 回复头
* @param request 请求器
* @return
*/
private static Response repair(Response response,Request.Builder request){
if(response==null)return response;
if(response.code()==307){
String url = response.header("Location");
Call call = OkClient.newCall(request.url(url).build());
try {
response = call.execute();
if (response.isSuccessful()) {
return response;
}
} catch (IOException e) {
e.printStackTrace();
throw Core.wrapThrow(e);
}
}
return response;
}
/**
* 异步请求
* @param url 服务路径
* @param data 请求数据
* @param method 请求方式
* @param header 请求头
* @param callback 回调处理
*/
public static Receipt requestByAsync(String url,Object data,String method,Record header,Action1 callback){
return requestByAsync(url,data,method,header,callback,null,null);
}
/**
* 异步请求
* @param url 服务路径
* @param data 请求数据
* @param method 请求方式
* @param header 请求头
* @param callback 回调处理
* @param onRequest 请求处理
* @param onResponse 回复处理
*/
public static Receipt requestByAsync(String url,Object data,String method,Record header,Action1 callback,Action1 onRequest, Action2 onResponse){
if(Strings.isBlank(url))return new Receipt(false,"访问地址未填写");
if (Strings.isBlank(method)) method = "post";
try {
String bodyString = toFormData(data,true);
// if(url.startsWith("${host}")){
// url.replace("${host}",WebContext.getHost());
// }
Request.Builder request = new Request.Builder().url(url);
switch (method.toLowerCase()){
case "post":
request.post(createRequestBody(bodyString,URLENCODED));
break;
case "put":
request.put(createRequestBody(bodyString,URLENCODED));
break;
case "delete":
request.delete(createRequestBody(bodyString,URLENCODED));
break;
default:
request.url(url+(url.contains("?")?"&"+bodyString:"?"+bodyString)).get();
break;
}
if (header != null && header.size() > 0) {
header.forEach((k, v) -> {
if (Regex.isMatch(k, "(accept)|(connection)|(content-length)|(content-type)|(host)|(expect)|(if-modified-since)|(accept-encoding)"))
return;
if(v==null)return;
String value = v.toString();
//value = encode(value);//处理中文
//以_name_形式,为Ladder类库增加
if (Regex.isMatch(k, "_(\\w*)_")) {
request.header(k, Json.toJson(value));
return;
}
switch (k.toLowerCase()) {
default:
request.header(k, Json.toJson(value));
break;
}
//request.header(k,v==null?"":v.toString());
});
}
if(onRequest!=null)onRequest.invoke(request);
//创建"调用" 对象
Call call = OkClient.newCall(request.build());
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("ladder-httperror:"+url+","+e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
try {
if(callback!=null) {
if (response.isSuccessful()) {
callback.invoke((ResponseBody) response.body());
} else callback.invoke(null);
}
} catch (Exception e) {
System.out.println("ladder-httperror:"+(response!=null?"["+response.code()+"]":"")+url+","+e.getMessage());
e.printStackTrace();
}finally {
response.close();
}
}
});
return new Receipt();
} catch (Exception e) {
System.out.println("ladder-httperror:"+url+","+e.getMessage());
return new Receipt(false,e.getMessage()).setData(e.toString());
}
}
/**
* 上传数据
* @param url 服务路径
* @param files 上传文件集合
* @param data 表单数据
*/
public static Receipt upload(String url, Collection files, Map data, Record header){
if (Core.isEmpty(files)) return new Receipt(false, "未有上传数据[204]");
Map record = new HashMap();
files.forEach(x -> record.put(x.getFormName() + ":" + x.getFileName(), x.getData()));
return upload(url, record, data,header);
}
/**
* 上传数据
* @param url 服务路径
* @param files 上传文件集合
* @param data 表单数据
* @return
*/
public static Receipt upload(String url, Map files, Map data,Record header){
if (Core.isEmpty(files)) return new Receipt(false, "未有上传数据[209]");
try{
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
if(data!=null){
data.forEach((k,v)->{
if(v!=null)
requestBodyBuilder.addFormDataPart(k,v.toString());
});
}
files.forEach((k,v)->{
String[] ks = k.split(":");
String formName = Collections.first(ks);
String filename = Collections.last(ks);
requestBodyBuilder.addFormDataPart(formName,filename,createRequestBody(v,MutilPart_Form_Data));
});
MultipartBody requestBody = requestBodyBuilder.build();
Request.Builder request = new Request.Builder().url(url).post(requestBody);
if (header != null && header.size() > 0) {
header.forEach((k, v) -> {
if (Regex.isMatch(k, "(accept)|(connection)|(content-length)|(content-type)|(host)|(expect)|(if-modified-since)|(accept-encoding)"))
return;
if (v == null) return;
String value = v.toString();
//value = encode(value);//处理中文
//以_name_形式,为Ladder类库增加
if (Regex.isMatch(k, "_(\\w*)_")) {
request.header(k, Json.toJson(value));
return;
}
switch (k.toLowerCase()) {
default:
request.header(k, Json.toJson(value));
break;
}
});
}
Response response = OkClient.newCall(request.build()).execute();
if (!response.isSuccessful()) return new Receipt(false).setData(response.code()+"["+response.body().string()+"]");
return new Receipt().setData(response.body().string());
}catch (Exception e){
return new Receipt(false,e.getMessage());
}
}
/**
* 下载文件
* @param url 网络地址
* @param filename 文件名称
* @return
*/
public static Receipt downFile(String url,String filename){
Request request = new Request.Builder()
.url(url)
.build();
try {
Response response = OkClient.newCall(request).execute();
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
File file = new File(filename);
String parent = file.getParent();
//储存下载文件的目录
File dir = new File(parent);
if (!dir.exists()) dir.mkdirs();
try {
is = response.body().byteStream();
fos = new FileOutputStream(file);
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.flush();
return new Receipt();
//下载完成
} catch (Exception e) {
return new Receipt(false,e.getMessage());
}finally {
try {
if (is != null) is.close();
if (fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
return new Receipt(false,e.getMessage());
}
}
/**
* 异步下载文件
* @param url 网络路径
* @param filename 文件名称
*/
public static void downFileByAsync(String url,String filename){
Request request = new Request.Builder()
.url(url)
.build();
OkClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len;
FileOutputStream fos = null;
String parent = new File(filename).getParent();
//储存下载文件的目录
File dir = new File(parent);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(filename);
try {
is = response.body().byteStream();
long total = response.body().contentLength();
fos = new FileOutputStream(file);
long sum = 0;
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
sum += len;
int progress = (int) (sum * 1.0f / total * 100);
//下载中更新进度条
//listener.onDownloading(progress);
}
fos.flush();
//下载完成
//listener.onDownloadSuccess(file);
} catch (Exception e) {
//listener.onDownloadFailed(e);
}finally {
try {
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
/**
* 获取服务主机地址
* @param url 路径
*/
public static String getResource(String url) {
String uri;
int index = url.indexOf("?");
if (index > -1) url = url.substring(0, index);
if (Regex.isMatch(url, "^\\s*http")) {
index = url.indexOf("/", 9);
uri = index > -1 ? url.substring(index + 1) : "";
} else {
url = Regex.replace(url, "^\\s*(\\.\\./)*", "");
uri = url;
}
return uri;
}
/**
* 向指定URL发送POST请求,并返回响应结果
*
* @param url 请求的URL
* @param data POST请求的数据
* @return 响应结果
*/
public static String post(String url, Record data) {
return request(url, data, "POST", null).getData();
}
/**
* 向指定URL发送GET请求,并返回响应结果的数据
*
* @param url 请求的URL
* @return 响应结果的数据
*/
public static String get(String url){
return request(url, null, "GET", null).getData();
}
/**
* 向指定URL发送GET请求,并返回响应结果的数据
*
* @param url 请求的URL
* @param data GET请求的参数
* @return 响应结果的数据
*/
public static String get(String url, Record data) {
return request(url, data, "GET", null).getData();
}
/**
* 网址转IP
* @param url 网络路径
*/
public static String toIp(String url) {
if(url==null)return null;
try {
java.net.URL address = new java.net.URL(url);
return InetAddress.getByName(address.getHost()).getHostAddress();
} catch (Exception e) {
return null;
}
}
private static TrustManager[] buildTrustManagers() {
return new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
}
private static OkHttpClient.Builder setSSL(OkHttpClient.Builder builder){
try{
TrustManager[] trustAllCerts = new TrustManager[1];
TrustManager tm = new TrustAllCerts();
trustAllCerts[0] = tm;
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
builder.sslSocketFactory(sc.getSocketFactory(), (X509TrustManager) tm);
builder.hostnameVerifier((hostname,session)->true);
return builder;
}catch (Exception e){
e.printStackTrace();
}
return builder;
}
private static SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
return ssfFactory;
}
private static class TrustAllCerts implements TrustManager,X509TrustManager {
//checkServerTrusted和checkClientTrusted 这两个方法好像是用于,server和client双向验证
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy