1 公司使用的java开发,okhttp java版本 早就不更新了。现在是Kotlin版本。
java
package com.sbas.mybledemohk;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
/**
* 基于HttpURLConnection的图片上传工具类
* 无第三方依赖,纯Java原生实现
*/
public class HttpImageUploader {
// 随机生成boundary分隔符(避免与内容冲突)
private static final String BOUNDARY = "----WebKitFormBoundary" + UUID.randomUUID().toString().replace("-", "");
// 换行符(必须用\r\n,HTTP协议规范)
private static final String CRLF = "\r\n";
/**
* 上传图片到指定接口
*
* @param uploadUrl 上传接口地址(如:http://localhost:8080/api/upload/image)
* @param imagePath 本地图片路径(如:D:/test.jpg)
* @return 服务器响应内容
* @throws Exception 上传异常
*/
public static String uploadImage(String uploadUrl, String imagePath) throws Exception {
// 1. 校验图片文件
File imageFile = new File(imagePath);
if (!imageFile.exists() || !imageFile.isFile()) {
throw new IllegalArgumentException("图片文件不存在或不是有效文件:" + imagePath);
}
// 2. 创建HTTP连接
URL url = new URL(uploadUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求方法
conn.setRequestMethod("POST");
// 允许输入/输出流(上传需要写请求体,下载需要读响应)
conn.setDoInput(true);
conn.setDoOutput(true);
// 禁用缓存
conn.setUseCaches(false);
// 设置超时时间(连接+读取)
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
// 3. 设置请求头(核心:指定multipart/form-data格式)
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
conn.setRequestProperty("User-Agent", "Java-HttpURLConnection");
// 4. 构建请求体并写入输出流
OutputStream out = new DataOutputStream(conn.getOutputStream());
// 4.1 写入文件参数的描述头
StringBuilder paramHeader = new StringBuilder();
//orgId = "1892116295849435138" userid = "123456" 多个参数这里复制多份
paramHeader.append("--").append(BOUNDARY).append(CRLF);
paramHeader.append("Content-Disposition: form-data; name=\"" + "orgId" + "\"").append(CRLF).append(CRLF);
paramHeader.append("1892116295849435138");
paramHeader.append(CRLF);
paramHeader.append("--").append(BOUNDARY).append(CRLF);
paramHeader.append("Content-Disposition: form-data; name=\"" + "userid" + "\"").append(CRLF).append(CRLF);
paramHeader.append("123456");
paramHeader.append(CRLF);
//orgId = "1892116295849435138" userid = "123456" end
paramHeader.append("--").append(BOUNDARY).append(CRLF);
// Content-Disposition:指定参数名、文件名
paramHeader.append("Content-Disposition: form-data; name=\"").append("file").append("\"; filename=\"")
.append(imageFile.getName()).append("\"").append(CRLF);
// Content-Type:指定文件类型(图片通用为image/*)
paramHeader.append("Content-Type: image/").append(getFileSuffix(imageFile.getName())).append(CRLF);
// paramHeader.append("Content-Type: image/*").append(CRLF);
// 空行(必须,分隔描述头和文件内容)
paramHeader.append(CRLF);
// 写入描述头(转字节流,UTF-8编码)
out.write(paramHeader.toString().getBytes(StandardCharsets.UTF_8));
// 4.2 写入图片文件流(核心)zqkaoping.apk
try (FileInputStream fis = new FileInputStream(imageFile)) {
byte[] buffer = new byte[8192]; // 8KB缓冲区,提升效率
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
// 4.3 写入结束分隔符(必须以--boundary--结尾)
out.write((CRLF + "--" + BOUNDARY + "--" + CRLF).getBytes(StandardCharsets.UTF_8));
out.flush(); // 刷新输出流,确保所有数据发送
// 5. 处理服务器响应
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// 读取响应内容
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
return response.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
// 读取错误响应(便于排查问题)
try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8))) {
StringBuilder errorMsg = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
errorMsg.append(line);
}
throw new Exception("上传失败,响应码:" + responseCode + ",错误信息:" + errorMsg);
}
}
}
/**
* 工具方法:获取文件后缀(如test.jpg返回jpg)
*/
private static String getFileSuffix(String fileName) {
if (fileName == null || fileName.lastIndexOf(".") == -1) {
return "jpeg"; // 默认jpeg
}
return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
}
// 测试方法
public static void main(String[] args) {
try {
// 替换为你的实际上传接口地址
String uploadUrl = "http://api.test-smart-sports.siboasi-data.com/smartsCore/open/footballeval/search/face";
// 替换为你的本地图片路径
String imagePath = "D:/test.png";
// 后端接收的文件参数名(需和后端一致)
String result = uploadImage(uploadUrl, imagePath);
System.out.println("上传成功,服务器响应:" + result);
} catch (Exception e) {
System.err.println("上传失败:" + e.getMessage());
e.printStackTrace();
}
}
}
一个参数 多个参数就复制多个
java
//orgId = "1892116295849435138" userid = "123456" 多个参数这里复制多份
paramHeader.append("--").append(BOUNDARY).append(CRLF);
paramHeader.append("Content-Disposition: form-data; name=\"" + "orgId" + "\"").append(CRLF).append(CRLF);
paramHeader.append("1892116295849435138");
paramHeader.append(CRLF);