欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

java 使用 multipart/form-data POST 上传文件

最编程 2024-06-23 11:20:03
...

最近写微信API的“上传临时素材接口”时,正好遇到该需求,经百度解决完毕后整理发出。

主逻辑参照下链接完成,这已经是一个好用的demo:构建multipart/form-data实现文件上传 - _herbert - 博客园构建multipart/form-data实现文件上传 通常文件上传都是通过form表单中的file控件,并将form中的content-type设置为multipart/form-data。现在我们https://www.cnblogs.com/yfrs/p/uploadbyjavacode.html在此基础上加入https请求的实现。下面内容的请求体格式与上文略有不同,是我参考微信API进行修改后的结果。希望能够帮助到大家。

package com.sa.util.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.UUID;

/**
 * @Classname: FileUploadUtil
 * @Description: 上传文件工具类:https请求使用postUploadSSL,http使用postUpload。主逻辑参照:https://www.cnblogs.com/yfrs/p/uploadbyjavacode.html
 * @author: 流泪兔兔头
 */
public class FileUploadUtil {

	private static final Logger log = LoggerFactory.getLogger(FileUploadUtil.class);

	/**
	 * @Title: postUploadSSL
	 * @Description: https上传文件方法
	 * @param url      请求接口
	 * @param file     文件实体
	 * @param fileName 文件名
	 * @author: 流泪兔兔头
	 */
	public static String postUploadSSL(String url, File file, String fileName) {
		StringBuilder result = new StringBuilder();
		try {
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
			URL console = new URL(url);
			HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
			// 构建请求头
			conn.setRequestMethod("POST");
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			conn.setRequestProperty("Charset", "UTF-8");
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);

			// 设置输出流
			String newLine = "\r\n";
			String boundaryPrefix = "--";
			String boundary = "----" + UUID.randomUUID().toString();
			conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
			OutputStream out = conn.getOutputStream();
			StringBuilder sb = new StringBuilder();

			// 构建请求体
			sb.append(newLine);
			sb.append(boundaryPrefix);
			sb.append(boundary);
			sb.append(newLine);
			String nameTmp = file.getName();
			String typeName = nameTmp.substring(nameTmp.lastIndexOf("."));
			sb.append("Content-Disposition: form-data; name=\"media\";filename=\"").append(fileName).append(typeName).append("\";filelength=").append(file.length());
			sb.append("Content-Type: application/octet-stream");
			sb.append(newLine);
			sb.append(newLine);

			out.write(sb.toString().getBytes());
			FileInputStream in = new FileInputStream(file);
			byte[] bufferOut = new byte[1024];
			int bytes = 0;
			while ((bytes = in.read(bufferOut)) != -1) {
				out.write(bufferOut, 0, bytes);
			}
			in.close();
			byte[] end_data = (newLine + boundaryPrefix + boundary + boundaryPrefix + newLine).getBytes();
			out.write(end_data);
			out.flush();
			out.close();

			// 配置SSL
			conn.setSSLSocketFactory(sc.getSocketFactory());
			conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
			conn.connect();

			// 读取请求返回信息
			InputStream is = conn.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String ret = "";
			while ((ret = br.readLine()) != null) {
				if (!ret.trim().equals("")) {
					result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
				}
			}
			log.info("recv - {}", result);
			conn.disconnect();
			br.close();
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
			log.error("文件上传失败{}", e.getMessage());
		}
		return result.toString();
	}

	/**
	 * @Title: TrustAnyTrustManager
	 * @Description: SSL用证书信任管理器
	 * @author: 流泪兔兔头
	 */
	private static class TrustAnyTrustManager implements X509TrustManager {
		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) {
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) {
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[]{};
		}
	}

	/**
	 * @Title: TrustAnyHostnameVerifier
	 * @Description: SSL用主机名验证
	 * @author: 流泪兔兔头
	 */
	private static class TrustAnyHostnameVerifier implements HostnameVerifier {
		@Override
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}
}

推荐阅读