废话:这里使用的是HttpUrlConnection,httpclient没有试过,这篇文章也是收集了很多大佬的成果,但是由于太久远了找不到原文了,如果有大佬看到提醒一下,愿意贴上原文链接的哈,抱歉抱歉,现在实现了同时传输文件和数据,但是response返回的文件和数据只能接收一个,如果大家有同时接收的方法,望告知,谢谢大家了。
需求:其实就是服务器间通过http进行通讯,不走前端的那种,公司需求给某个网址主动发文件流,并且接收response中的反馈文件流或者错误信息。
连接工具类HttpUrlConnection.java,现在支持传多个数据,一个文件,如果需要多个文件,照着改改应该没问题的
@Component public class HttpUrlConnection { //头部格式 private static final String nextLine = " "; private static final String twoHyphens = "--"; //随便写一个 private static final String boundary = java.util.UUID.randomUUID().toString(); /** * @Description:java项目的服务端之间的通信 * @Param: [requestUrl,请求url * jsessionId, 浏览器的访问的Cookie,即被访问的服务端的session。若被访问的服务器没有做url过滤器,则该参数可以为null。 * file, 发送出去的文件 * feedbackFile, 收到的反馈文件存放位置 * name,对方用来接收文件的名字 * params,要传的参数 * @Return: java.util.Map * @Author: Liting * @Date: 2019-11-26 08:54 */ public static Map httpUrlConnection(String requestUrl, String jsessionId, File file, String feedbackFile, String name, Map<String,String> params) throws IOException { HttpURLConnection con = (HttpURLConnection) new URL(requestUrl).openConnection(); if (!Utils.isEmpty(jsessionId)) { con.setRequestProperty("Cookie", "JSESSIONID=" + jsessionId); } // 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在 // http正文内,因此需要设为true, 默认情况下是false; con.setDoOutput(true); // 设置是否从httpUrlConnection读入,默认情况下是true; con.setDoInput(true); // 设定请求的方法为"POST",默认是GET con.setRequestMethod("POST"); // Post 请求不能使用缓存 con.setUseCaches(false); //设置接收返回值的格式 con.setRequestProperty("Accept", "text/plain, */*"); //设置接收编码 con.setRequestProperty("Accept-Language", "zh-cn"); con.setRequestProperty("Host","127.0.0.1"); //设置请求参数格式以及boundary分割线 con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); con.setRequestProperty("User-Agent"," WinHttpClient"); //开启长连接可以持续传输 con.setRequestProperty("Connection", "Keep-Alive");
//连接超时时间20秒 con.setConnectTimeout(20000);
//读取超时时间20秒 con.setReadTimeout(20000); OutputStream out = con.getOutputStream(); //分隔符头部 //拼接参数 if (!Utils.isEmpty(params)){ int i = 0; for (String paramName : params.keySet()){ StringBuffer strBufparam = new StringBuffer(); strBufparam.append(twoHyphens); strBufparam.append(boundary); strBufparam.append(nextLine); strBufparam.append("Content-Disposition: form-data;name=""+paramName+"""); strBufparam.append(nextLine); strBufparam.append("Content-Type: " + "text/plain"); strBufparam.append(nextLine); strBufparam.append("Content-Length: " + params.get(paramName).getBytes().length); strBufparam.append(nextLine); strBufparam.append(nextLine); strBufparam.append(params.get(paramName)); i++; if (i!=params.size()){ strBufparam.append(nextLine); } out.write(strBufparam.toString().getBytes()); } } //拼接文件 if (!Utils.isEmpty(file)){ StringBuffer strBufFile = new StringBuffer(); strBufFile.append(nextLine); strBufFile.append(twoHyphens); strBufFile.append(boundary); strBufFile.append(nextLine); strBufFile.append("Content-Disposition: form-data; name=""+name+""; filename="" + file.getName() + """); strBufFile.append(nextLine); strBufFile.append("Content-Type: " + "application/x-tar"); strBufFile.append(nextLine); strBufFile.append("Content-Length: " + file.length()); strBufFile.append(nextLine); strBufFile.append(nextLine); //写入输出流 out.write(strBufFile.toString().getBytes()); //读取本地文件流 FileInputStream inputStream = new FileInputStream(file); byte[] data = new byte[2048]; int len = 0; int sum = 0; while ((len = inputStream.read(data)) != -1) { //将读取到的本地文件流读取到HttpsURLConnection,进行上传 out.write(data, 0, len); sum = len + sum; } //文件写入完成后加回车 out.write(nextLine.getBytes()); inputStream.close(); } //写入结束分隔符 String footer = nextLine + twoHyphens + boundary + twoHyphens + nextLine; out.write(footer.getBytes()); out.flush(); out.close(); con.connect(); int responseCode = con.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { if (!Utils.isEmpty(feedbackFile)) {//有返回文件的时候 String fileName = ""; try { fileName = con.getHeaderField(1).substring(21, con.getHeaderField(1).length() - 1); fileName = "EBDT"+fileName.split("_")[1]; System.out.println(fileName); }catch (Exception e){ return null; } BufferedInputStream in = new BufferedInputStream(con.getInputStream()); File f = new File(feedbackFile); if (!f.exists()) { f.mkdirs(); } File res = new File(feedbackFile+"/"+fileName); FileOutputStream fos = new FileOutputStream(res); byte[] by = new byte[1024]; int length = 0; while ((length = in.read(by)) != -1) { fos.write(by, 0, length); } fos.close(); in.close(); con.disconnect(); if (Utils.isEmpty(fos)) { return null; } //处理接收到的文件 //保存到本地 Map map = new HashMap(); map.put("fileName",fileName); return map; }else{ //接收到的return中的值 BufferedReader br = new BufferedReader(new InputStreamReader( con.getInputStream())); String s = br.readLine(); br.close(); con.disconnect(); try{ if (!Utils.isEmpty(s)){ Object m = JSONObject.parse(s); Map map = (Map) m; return map; } }catch (Exception e){ Map map = new HashMap(); map.put("feedback",s); return map; } } return new HashMap(); } else { con.disconnect(); return null; } } }
main方法测试
public static void main(String[] args) throws IOException { Map<String,String> map = new HashMap<>(); map.put("name","张三"); map.put("age","23"); File file = new File("D:\1.xml"); Map map1 = HttpUrlConnection.httpUrlConnection("http://127.0.0.1/user/addUser", "69e4baee-ff22-4cdf-a73b-6156c5d6d2c1", file, "", "files", map); System.out.println(map1); }
结果
到这就是全部了,如有问题欢迎留言