好久没发帖了,难的清闲。记录下几个坑:
公司使用c++开发了核心功能(貌似有产权),对外开放restful风格的接口。我的项目就是调用这些接口,定制化客户的具体业务场景。
其中一个接口就是使用post方式发送一个文件,然后它给我们返回一个分析后的信息,如此而已。
由于我们项目用了spring,我当然就尝试了spring封装的restTemplate。但发现其他和文件无关的接口,都没问题。无论post、get、delete。。。。,只有这个文件接口就是失败。
我心里打鼓,不会触及底层http了吧。于是我继续写测试案例,做了个java实现的接受文件的服务接口的小项目,再尝试使用我们项目去调用它,发现一切ok。
这下我蒙了。
最后贴上我使用jdk原生的方案:
/**
* @note 以POST方式上传文件
*
* @param requestUrl
* @param file
* @return
*/
public static String postUseUrlConnection(String requestUrl, File file) {
String end = "\r\n";
String twoHyphens = "--";
String boundary = "*****"+UUID.randomUUID().toString();
//String newName = "image.jpg";
StringBuffer sb = new StringBuffer();
try {
URL url = new URL(requestUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
// 允许Input、Output,不使用Cache
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
// 设置以POST方式进行传送
con.setRequestMethod("POST");
// 设置RequestProperty
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");
con.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
// 构造DataOutputStream流
DataOutputStream ds = new DataOutputStream(con.getOutputStream());
ds.writeBytes(twoHyphens + boundary + end);
// ds.writeBytes("Content-Disposition: form-data; name=\"body\";filename=\"" + file.getName() + "\"" + end);
ds.writeBytes("Content-Disposition: form-data; name=\"body\";filename=\""+UUID.randomUUID().toString()+"\"" + end);
ds.writeBytes(end);
// 构造要上传文件的FileInputStream流
FileInputStream fis = new FileInputStream(file);
// 设置每次写入1024bytes
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int length = -1;
// 从文件读取数据至缓冲区
while ((length = fis.read(buffer)) != -1) {
// 将资料写入DataOutputStream中
ds.write(buffer, 0, length);
}
ds.writeBytes(end);
ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
// 关闭流
fis.close();
ds.flush();
// 获取响应流
InputStream is = con.getInputStream();
int ch;
while ((ch = is.read()) != -1) {
sb.append((char) ch);
}
// 关闭DataOutputStream
ds.close();
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}