由于工作上的需求,这两天对接了个php的接口,上传文件必须使用固定格式,下面看下需要上传的格式,从图片中可以看出,多个图片数据是使用boundary分割的,并且在每个数据体内(即从分割符到下一个分割符),除了name以外,还必须拼接特定字段,例如pictype isurl等等,这个比较重要,因为使用RestTemplate 和hettpClient方式,无法拼接该字符(本人确实第一次写,如果哪位大神可以用这两种方式写出来,希望能够留言,交流学习)
下面来说下如何解决该类问题的
首先在使用httpclient和RestTemplate时候,拼接header,实体数据没任何问题,问题出现在了分割符,以及每个实体里面Content-Dispositon 的内容,这两种方式我没有找到好的方式来填充自定义的值,http里面可以很好解决该问题,因为可以自定义内容,下面是主要代码
//随便定义分割符String boundary="--7daf10c20d06";URL urlCon=new URL(url);HttpURLConnection connection= (HttpURLConnection) urlCon.openConnection();connection.setRequestMethod("POST");connection.setRequestProperty("Host","xxxxx");connection.setRequestProperty("Accept","image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*");connection.setRequestProperty("Accept-Language","zh-cn");connection.addRequestProperty("Content-Type","multipart/form-data; boundary="+boundary);connection.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; CIBA; .NET CLR 2.0.50727)");connection.addRequestProperty("Connection","close");connection.setRequestProperty("Cache-Control","no-cache");connection.addRequestProperty("Charset","UTF-8");// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在// http正文内,因此需要设为true, 默认情况下是false;connection.setDoOutput(true);//设置是否从httpUrlConnection读入,默认情况下是true;connection.setDoInput(true);// Post 请求不能使用缓存 ?connection.setUseCaches(false);connection.setConnectTimeout(20000);connection.connect();StringBuilder contentBody1 = new StringBuilder();StringBuilder contentBody2 = new StringBuilder();StringBuilder contentBody3= new StringBuilder();DataOutputStream dataOutputStream=new DataOutputStream(connection.getOutputStream());//这里我将url转换成二进制流byte[] bytes = httpDownloadServer.downloadImage("xxx.jpg");byte[] end_data=("\r\n----7daf10c20d06--\r\n").getBytes();String json = "{ sName:\"张三\", sNation:\"test\", sBirthDate:\"-01-30\", sAddress:\"南山区\", sIdNumber:\"13301112345\", sStartDate:\"-01-30 23:00:00\", sEndDate:\"-02-30\",sCheckDate:\"-01-30 23:00:00\", iResult:0, bAlarm:true, sRec:\"\"} ";//第一部分 特别注意,自定义拼接以定要按照该格式,回车换行,\r\n一定按照下面格式来,缺少一个都会报500错误contentBody1.append("--"+boundary);contentBody1.append("\r\n");contentBody1.append("Content-Disposition:form-data;name=\"userfile\";pictype=0&isurl=1&piclen=10011;filename=\"1.jpg\"");contentBody1.append("\r\n");contentBody1.append("Content-Type:image/jpeg");contentBody1.append("\r\n");contentBody1.append("\r\n");dataOutputStream.write(contentBody1.toString().getBytes());dataOutputStream.write(bytes, 0, bytes.length);dataOutputStream.write("\r\n".getBytes());//第二部分contentBody2.append("--"+boundary);contentBody2.append("\r\n");contentBody2.append("Content-Disposition:form-data;name=\"userfile\";pictype=1&isurl=1&piclen=10011;filename=\"2.jpg\"");contentBody2.append("\r\n");contentBody2.append("Content-Type:image/jpeg");contentBody2.append("\r\n");contentBody2.append("\r\n");dataOutputStream.write(contentBody2.toString().getBytes());dataOutputStream.write(bytes, 0, bytes.length);dataOutputStream.write("\r\n".getBytes());//第三部分contentBody3.append("--"+boundary);contentBody3.append("\r\n");contentBody3.append("Content-Disposition:form-data; name=\"userfile\";datatype=json&datalen=126");contentBody3.append("\r\n");contentBody3.append("Content-Type: text/plain");contentBody3.append("\r\n");contentBody3.append("\r\n");contentBody3.append(json);contentBody3.append("\r\n");dataOutputStream.write(contentBody3.toString().getBytes());dataOutputStream.write(end_data);dataOutputStream.flush();InputStream inputStream=connection.getInputStream();byte[] data=new byte[1024];StringBuffer sb1=new StringBuffer();int length=0;while ((length=inputStream.read(data))!=-1){String returns=new String(data, Charset.forName("utf-8"));sb1.append(returns);}String message=sb1.toString();System.out.println(message);inputStream.close();dataOutputStream.close();connection.disconnect();
这里就不写url转换二进制代码了,比较简单。