Java POST请求发送文件同时发送参数

本文内容如有错误、不足之处,欢迎技术爱好者们一同探讨,在本文下面讨论区留言,感谢。欢迎转载,转载请注明出处(https://blog.csdn.net/feng_xiaoshi/article/details/106083621),谢谢。

简介

通常的POST请求的业务场景,不是上传文件,就是提交表单,很少遇到上传文件同时需要提交表单信息。
文件和参数

Request 信息

本文主要就是解决这个问题,下面是 Jmeter 在测试时,Request 信息:

POST http://localhost/post/fileAndParams

POST data:
--O3UEgNYE7QvWW8f30_NeKK8s436bFmfnhg5j
Content-Disposition: form-data; name="param1"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

value1
--O3UEgNYE7QvWW8f30_NeKK8s436bFmfnhg5j
Content-Disposition: form-data; name="param2"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

value2
--O3UEgNYE7QvWW8f30_NeKK8s436bFmfnhg5j
Content-Disposition: form-data; name="file"; filename="text.txt"
Content-Type: application/vnd.ms-execl
Content-Transfer-Encoding: binary

<actual file content, not shown here>
--O3UEgNYE7QvWW8f30_NeKK8s436bFmfnhg5j--


[no cookies]

使用 Java 的 HttpURLConnection 编码

根据上面的 Request 信息,结合Java 的 HttpURLConnection 编写出下面的请求方法。

/**
 * POST 请求
 * @param requestUrl 请求url
 * @param inputStream 输入流
 * @param fileName 文件名
 * @param params 参数集合
 */
public static String postInputStream(String requestUrl,InputStream inputStream, String fileName,
			List<NameValuePair> params) throws IOException {
	URL url = new URL(requestUrl);
	HttpURLConnection conn = (HttpURLConnection) url.openConnection();
	try {
		// 上面 Jmeter 请求中携带的信息,可以自定义任意字符串
		String boundary = "O3UEgNYE7QvWW8f30_NeKK8s436bFmfnhg5j"; 
		// enter功能
		String enter = "\r\n";
		
		// 连接做输入、输出
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod("POST");
		conn.setUseCaches(false);
		conn.setInstanceFollowRedirects(true);
		// 模拟数据类型 不要忘记添加 boundary 这里的 boundary 类似于 序列化中的 serialVersionUID 
		// 但是作用却是连接开始和结束的标识
		conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
		conn.connect();
		
		// 数据输出流,从服务器输出到网络端
		DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
		
		// 组合发送数据格式,模拟 Jmeter
		String fileString = "--" + boundary + enter + "Content-Type: application/octet-stream" + enter
				+ "Content-Disposition: form-data; name=\"file\"" + "; filename= \"" + fileName + "\"" + enter
				+ enter;
		// 写入数据流
		dos.writeBytes(fileString);
		byte[] b = new byte[1024];
		int len = 0;
		while ((len = inputStream.read(b, 0, 1024)) != -1) {
			dos.write(b, 0, len);
		}
		// 循环放置参数信息
		for (NameValuePair param : params) {
			String part = enter + "--" + boundary + enter + "Content-Type: text/plain" + enter
					+ "Content-Disposition: form-data; name=\"" + param.getName() + "\"" + enter + enter
					+ param.getValue() + enter;
	
			dos.writeBytes(part);
		}
		// 结束
		String end = "--" + boundary + "--";
		dos.writeBytes(end);
		// 刷新流
		dos.flush();
		dos.close();
		// 得到响应流
		InputStream responseStream = conn.getInputStream();
		// 获取响应
		BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream));
		String line;
		StringBuilder message = new StringBuilder();
		while ((line = reader.readLine()) != null) {
			message.append(line);
		}
		// 获取返回信息
		return message.toString();
	} finally {
		inputStream.close();
		conn.disconnect();
	}
}

通过代码上的注释,结合 Jmeter Request 信息,相信能够很容易理解代码逻辑。

上面的代码是通过 HttpURLConnection 进行的直连,技术深度不高,代码理解需要借助 Jmeter Request 信息。

使用 apache 的 HttpPost 编码

下面是 Post 的进化版

public static String postInputStream(String requestUrl,InputStream inputStream, String fileName,
		List<NameValuePair> params) throws IOException {
        try (inputStream;CloseableHttpClient httpClient = HttpClients.createDefault();){
        	// 创建 POST请求
			HttpPost httpPost = new HttpPost(requestUrl);
			// 构建多组件 Entrity构建器
			MultipartEntityBuilder builder = MultipartEntityBuilder.create();
			builder.setCharset(Charsets.UTF_8);
			builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
			//文件传输http请求头(multipart/form-data)
			builder.addBinaryBody("file", inputStream, ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
			//字节传输http请求头(application/json)
			ContentType contentType = ContentType.create("application/json", Charsets.UTF_8);
            for (NameValuePair param : params) {
            	// 传输字节流
            	builder.addTextBody(param.getName(), param.getValue(), contentType);
            }
             HttpEntity entity = builder.build();
             httpPost.setEntity(entity);
             HttpResponse response = httpClient.execute(httpPost);
             // 执行提交
             HttpEntity responseEntity = response.getEntity();
             if (responseEntity != null) {
                 // 将响应内容转换为字符串
                 return EntityUtils.toString(responseEntity, Charsets.UTF_8);
             }
        } catch (Exception e) {
             throw new BusinessException("post请求失败,"+e.getMessage());
        }
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值