Java 编写 HTTP POST访问接口,传递普通参数与图片文件参数

烈酒焚心 提交于 2019-12-07 10:07:32

在开发中,我们使用的比较多的HTTP请求方式基本上就是GET、POST。其中GET用于从服务器获取数据,POST主要用于向服务器提交一些表单数据,例如文件上传等。而我们在使用HTTP请求时中遇到的比较麻烦的事情就是构造文件上传的HTTP报文格式,这个格式虽说也比较简单,但也比较容易出错。今天我们就一起来学习HTTP POST的报文格式以及通过Java来模拟文件上传的请求。

啥都不说直接上代码,能用记得点赞:

/**
	 * 
	 * @Function: HttpClient.java 上传文件到指定地址URL
	 * @param urlStr 请求地址
	 * @param files  文件map集合
	 * @param params 参数集合
	 * 
	 * @version: v1.0.0
	 * @author: 白毅
	 * @date: 2019年2月22日 下午5:33:41
	 */
	public String uploadFile(String urlStr, Map<String, File> files, Map<String, String> params) {
		try {
			// 换行符
			final String LINEND = "\r\n", MULTIPART_FROM_DATA = "multipart/form-data", PREFIX = "--";
			String BOUNDARY = java.util.UUID.randomUUID().toString();
			boolean isFirst = true;
			// 服务器的上传地址
			URL url = new URL(urlStr);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			// 设置为POST情
			conn.setRequestMethod("POST");
			// 发送POST请求必须设置如下两行
			conn.setDoInput(true);// 允许输入
			conn.setDoOutput(true);// 允许输出
			conn.setUseCaches(false); // 不允许使用缓存
			// 设置请求头参数
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("Charsert", "UTF-8");
			conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + "; boundary=" + PREFIX + PREFIX + BOUNDARY);
			conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36");

			// 首先组拼文本类型的参数
			StringBuffer sb = new StringBuffer();
			sb.append(LINEND);
			for (Map.Entry<String, String> entry : params.entrySet()) {
				// 参数头
				sb.append(PREFIX);
				sb.append(PREFIX);
				sb.append(PREFIX);
				sb.append(BOUNDARY);
				sb.append(LINEND);
				sb.append("Content-Disposition: form-data; name=\"");
				sb.append(entry.getKey());
				sb.append("\"");
				// 参数头设置完以后需要两个换行,然后才是参数内容
				sb.append(LINEND);
				sb.append(LINEND);
				sb.append(entry.getValue());
				sb.append(LINEND);
			}
			// 文件数据传输
			OutputStream out = new DataOutputStream(conn.getOutputStream());

			for (Map.Entry<String, File> file : files.entrySet()) {
				if (!isFirst) {
					sb = new StringBuffer();
				}
				// 参数头
				sb.append(PREFIX);
				sb.append(PREFIX);
				sb.append(PREFIX);
				sb.append(BOUNDARY);
				sb.append(LINEND);
				sb.append("Content-Disposition: form-data; name=\"");
				sb.append(file.getKey());
				sb.append("\";");
				sb.append(" filename=\"");
				sb.append(file.getKey());
				sb.append("\"");
				sb.append(LINEND);
				sb.append("Content-Type: ");
				sb.append(new MimetypesFileTypeMap().getContentType(file.getValue().getName()));
				// 参数头设置完以后需要两个换行,然后才是参数内容
				sb.append(LINEND);
				sb.append(LINEND);
				// 将参数的数据写入到输出流中
				out.write(sb.toString().getBytes());
				// 数据输入流,用于读取文件数据
				InputStream is = new FileInputStream(file.getValue());
				DataInputStream in = new DataInputStream(is);
				byte[] bufferOut = new byte[2048];
				int bytes = 0;
				// 每次读2KB数据,并且将文件数据写入到输出流中
				while ((bytes = in.read(bufferOut)) != -1) {
					out.write(bufferOut, 0, bytes);
				}
				// 最后添加换行
				out.write(LINEND.getBytes());
				in.close();
				isFirst = false;
			}
			// 定义最后数据分隔线
			sb.append(PREFIX).append(PREFIX).append(PREFIX).append(BOUNDARY).append(PREFIX);
			// 写上结尾标识
			out.write(sb.toString().getBytes());
			out.flush();
			out.close();

			// 得到响应码
			int res = conn.getResponseCode();
			StringBuffer buffer = new StringBuffer();
			if (res == 200) {
				// 读取返回数据
				BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
				String line = null;
				while ((line = reader.readLine()) != null) {
					buffer.append(line).append("\n");
				}
				reader.close();
			}
			conn.disconnect();
			return buffer.toString();
		} catch (Exception e) {
			System.out.println("发送POST请求出现异常!" + e);
			e.printStackTrace();
		}
		return "";
	}

Postman 接口测试工具 简单方便点击下载

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!