FLASK与JAVA的文件互传并带参数以及流上传(单文件互传亲测)
JAVA:
flask:
JAVA代码:FileUploader4514.java
/*** HttpClient 4.5.14 文件上传工具类*/
public class FileUploader4514 {// 默认配置private static final int DEFAULT_CONNECT_TIMEOUT = 30000; // 30秒private static final int DEFAULT_SOCKET_TIMEOUT = 60000; // 60秒/*** 上传文件到指定URL*/public static UploadResult upload(String url, File file,Map<String, String> textParams) throws IOException {return upload(url, file, file.getName(), textParams, null);}/*** 上传文件(带自定义配置)*/public static UploadResult upload(String url, File file, String fileName,Map<String, String> textParams,RequestConfig requestConfig) throws IOException {if (requestConfig == null) {requestConfig = createDefaultRequestConfig();}try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build()) {HttpPost httpPost = new HttpPost(url);// 构建多部分实体MultipartEntityBuilder builder = MultipartEntityBuilder.create();builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);builder.setCharset(StandardCharsets.UTF_8);// 添加文件FileBody fileBody = new FileBody(file,ContentType.DEFAULT_BINARY,fileName);builder.addPart("file", fileBody);// 添加文本参数if (textParams != null) {for (Map.Entry<String, String> entry : textParams.entrySet()) {StringBody paramBody = new StringBody(entry.getValue(),ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8));builder.addPart(entry.getKey(), paramBody);}}HttpEntity multipartEntity = builder.build();httpPost.setEntity(multipartEntity);// 添加请求头(可选)httpPost.setHeader("User-Agent", "FileUploader/1.0");// 执行上传try (CloseableHttpResponse response = httpClient.execute(httpPost)) {int statusCode = response.getStatusLine().getStatusCode();String responseBody = EntityUtils.toString(response.getEntity());EntityUtils.consume(response.getEntity());return new UploadResult(statusCode, responseBody,statusCode >= 200 && statusCode < 300);}}}
/*** 通过输入流上传文件*/public static UploadResult uploadStream(String url, InputStream inputStream,String fileName, long fileSize,Map<String, String> textParams) throws IOException {try (CloseableHttpClient httpClient = HttpClients.createDefault()) {HttpPost httpPost = new HttpPost(url);MultipartEntityBuilder builder = MultipartEntityBuilder.create();// 使用InputStreamBody处理输入流InputStreamBody inputStreamBody = new InputStreamBody(inputStream,ContentType.DEFAULT_BINARY, fileName);builder.addPart("file", inputStreamBody);// 添加文件大小信息(如果已知)if (fileSize > 0) {builder.addTextBody("fileSize", String.valueOf(fileSize));}// 添加文本参数if (textParams != null) {textParams.forEach((key, value) ->builder.addTextBody(key, value,ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));}httpPost.setEntity(builder.build());try (CloseableHttpResponse response = httpClient.execute(httpPost)) {int statusCode = response.getStatusLine().getStatusCode();String responseBody = EntityUtils.toString(response.getEntity());return new UploadResult(statusCode, responseBody,statusCode >= 200 && statusCode < 300);}}}
}
JAVA的测试代码:
public static void main(String[] args) {try {// 示例2: 使用工具类上传(带参数)Map<String, String> params = new HashMap<>();params.put("description", "测试文件上传");params.put("tags", "12345");String urlSingle = "http://127.0.0.1:5000/api/upload";File file = new File("E:\\testWorkPlace\\testrun\\src\\HttpFlask\\upload.txt");//上传带参数的文件FileUploader4514.UploadResult uploadResult =FileUploader4514.upload(urlSingle, file, params);System.out.println("工具类上传结果: " + uploadResult);// 示例3: 使用输入流上传try (FileInputStream fis = new FileInputStream(file)) {FileUploader4514.UploadResult streamResult =FileUploader4514.uploadStream(urlSingle, fis, "E:\\testWorkPlace\\testrun\\src\\testHtt\\upload.txt",file.length(), params);System.out.println("流上传结果: " + streamResult);}
} catch (IOException e) {e.printStackTrace();}}
}
flask:
from flask import Flask, request, jsonify, render_template_string, send_file
import os
import uuid
from werkzeug.utils import secure_filename
from datetime import datetime
import magic # 用于更准确的文件类型检测
from datetime import datetime
import time
# # 安装 Windows 兼容版本
# pip install python-magic-bin
app = Flask(__name__)# 配置文件上传
app.config.update(UPLOAD_FOLDER='uploads',MAX_CONTENT_LENGTH=16 * 1024 * 1024, # 16MBALLOWED_EXTENSIONS={'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'doc', 'docx', 'zip'},SECRET_KEY='your-secret-key-here'
)# 用于存储上传统计信息
upload_stats = {'total_files': 0,'total_size': 0,'last_upload': None
}
# 创建上传目录
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)class FileUploader:"""文件上传工具类"""@staticmethoddef allowed_file(filename):"""检查文件扩展名"""return '.' in filename and \filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']@staticmethoddef generate_unique_filename(original_filename):"""生成唯一文件名"""timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")unique_id = str(uuid.uuid4())[:8]safe_name = secure_filename(original_filename)return f"{timestamp}_{unique_id}_{safe_name}"@staticmethoddef get_file_info(file_path):"""获取文件详细信息"""stat = os.stat(file_path)file_type = "unknown"try:# 使用python-magic检测文件类型import magicfile_type = magic.from_file(file_path, mime=True)except:# 备用方案:使用文件扩展名ext = os.path.splitext(file_path)[1].lower()file_type = f"application/{ext[1:]}" if ext else "unknown"return {'size': stat.st_size,'created_time': datetime.fromtimestamp(stat.st_ctime).isoformat(),'modified_time': datetime.fromtimestamp(stat.st_mtime).isoformat(),'type': file_type}@app.route('/api/upload', methods=['POST'])
def api_upload_file():"""API: 单文件上传"""try:if 'file' not in request.files:return jsonify({'success': False, 'error': '没有文件部分'}), 400file = request.files['file']description = request.form.get('description', '')tags = request.form.get('tags', '')print("description:",description)print("tags:",tags)if file.filename == '':return jsonify({'success': False, 'error': '没有选择文件'}), 400if not FileUploader.allowed_file(file.filename):return jsonify({'success': False, 'error': '不允许的文件类型'}), 400# 生成唯一文件名unique_filename = FileUploader.generate_unique_filename(file.filename)file_path = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)# 保存文件file.save(file_path)# 获取文件信息file_info = FileUploader.get_file_info(file_path)response_data = {'success': True,'message': '文件上传成功','file': {'id': unique_filename,'original_name': file.filename,'saved_name': unique_filename,'description': description,'tags': [tag.strip() for tag in tags.split(',')] if tags else [],'upload_time': datetime.now().isoformat(),**file_info}}return jsonify(response_data), 200except Exception as e:return jsonify({'success': False, 'error': str(e)}), 500
测试结果: