使用HttpURLConnection传递文件及参数

这几天在研发公司自用的excel校验工具,需要将后台存储的excel通过http传递到excel校验服务端同时传递相关的参数,查询网上的解决方案并没有适合的,这里结合网上提供的解决方案给出我自己的解决办法:

Http传输工具类方法:

    /**
	 * 文件上传
	 * @param httpUrl         文件上传的url
	 * @param uploadFilePath  需要上传的文件
	 * @param params          传递的参数
	 * @return
	 */
	@SuppressWarnings("finally")
	public static String uploadFile(String httpUrl, String uploadFilePath, Map params) {
		String end = "\r\n";
		String twoHyphens = "--";
		String boundary = "*****";
		DataOutputStream ds = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader reader = null;
		StringBuffer resultBuffer = new StringBuffer();
		String tempLine = null;
		try {
			// 统一资源
			URL url = new URL(httpUrl);
			// 连接类的父类,抽象类
			URLConnection urlConnection = url.openConnection();
			// http的连接类
			HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
			// 设置是否从httpUrlConnection读入,默认情况下是true;
			httpURLConnection.setDoInput(true);
			// 设置是否向httpUrlConnection输出
			httpURLConnection.setDoOutput(true);
			// Post 请求不能使用缓存
			httpURLConnection.setUseCaches(false);
			// 设定请求的方法,默认是GET
			httpURLConnection.setRequestMethod("POST");
			// 设置字符编码连接参数
			httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
			// 设置字符编码
			httpURLConnection.setRequestProperty("Charset", "UTF-8");
			// 设置请求内容类型
			httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
			// 设置DataOutputStream
			ds = new DataOutputStream(httpURLConnection.getOutputStream());
			String uploadFile = uploadFilePath;
			String filename = uploadFile;
			//======传递文件======
			ds.writeBytes(twoHyphens + boundary + end);
			ds.writeBytes("Content-Disposition: form-data; " + "name=\"excel" + "\";filename=\"" + filename
					+ "\"" + end);
			ds.writeBytes(end);
			FileInputStream fStream = new FileInputStream(uploadFile);
			int bufferSize = 1024;
			byte[] buffer = new byte[bufferSize];
			int length = -1;
			while ((length = fStream.read(buffer)) != -1) {
				ds.write(buffer, 0, length);
			}
			ds.writeBytes(end);
			//======传递文件end======
			//======传递参数======
			ds.writeBytes(twoHyphens + boundary + end);
			ds.writeBytes("Content-Disposition: form-data; " + "name=\"param" + "\";filename=\"" + params.toString()
					+ "\"" + end);
			ds.writeBytes(end);
			ds.writeBytes(end);
			//======传递参数end======
			fStream.close();
			ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
			ds.flush();
			if (httpURLConnection.getResponseCode() >= 300) {
				throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
			}
			if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
				inputStream = httpURLConnection.getInputStream();
				inputStreamReader = new InputStreamReader(inputStream);
				reader = new BufferedReader(inputStreamReader);
				tempLine = null;
				resultBuffer = new StringBuffer();
				while ((tempLine = reader.readLine()) != null) {
					resultBuffer.append(tempLine);
					resultBuffer.append("\n");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ds != null) {
				try {
					ds.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (inputStreamReader != null) {
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return resultBuffer.toString();
		}
	}

校验服务端部分代码:

    /**
     * excelFormatCheck
     * @param file
     * @param param
     * @return
     */
    @PostMapping("excelFormatCheck")
    public Object excelFormatCheck(@RequestParam(value = "excel", required = false) MultipartFile file, @RequestParam(value = "param", required = false) MultipartFile param) {
        Map result = new HashMap<>();
        Map> validateResult = new HashMap();
        List> validateResultLists = new ArrayList<>();
        try {
            if (null != file && !file.isEmpty()) {
                Gson gson = new Gson();
                Map mapParams = new HashMap();
                mapParams = gson.fromJson(param.getOriginalFilename(), mapParams.getClass());//转换传递的参数
                String templateId = mapParams.get("templateId");//获取模板id              
                result.put("code", 1);
                result.put("msg", "excel校验完成");
            } else {
                result.put("code", -2);
                result.put("msg", "未上传excel");
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.put("code", -1);
            result.put("msg", "excel校验接口异常");
        }
        return result;
    }

测试方法:

	public static void main(String[] args) {
		String path = "F:/aa.xls";
		Map map = new HashMap<>();
		map.put("templateId", "aa-dsa");
		String result = uploadFile("http://localhost:8002/exCheck/excelValidateCtl/excelFormatCheck", path, map);
		System.out.println(result);
	}

总结下简单说就是一旦我们将Content-Type设置为multipart/form-data原先通过k-v获取参数的方式就不再可行,因此这里除了传递真实的文件外,再传递一个仅记录文件名即所需传递参数的空文件,然后在服务端通过获取文件的文件名然后将其解析成参数即可。

你可能感兴趣的:(java开发)