使用工具:idea
框架:gradle、springboot
实现目标:使用 httpclient 发送文件/参数/json对象
method:post
主要用到的jar包:
compile group: 'net.sf.json-lib', name: 'json-lib', version: '2.4', classifier: 'jdk15'
//httpclient
// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime
compile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.3'
// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore
compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.6'
花了大半天终于写完这个测试类,能正常跑起来,下面主要贴出来两种 httpclient 的发送和接收,基本够用
特别注意:
1.文件和json对象是不能一起发送的,要发也是把json对象toString一下,见第一个方法
2.发送json对象,并用Requestbody接收,这种智能发对象,不能发文件,见第二个方法
预备几个方法,因为模拟数据用到的一样,所以先贴这几个公用方法:
//模拟文件数据,这里自己改成自己的文件就可以了
private static List
主函数:
/**
* 主函数
* @param args
* @throws Exception
*/
public static void main(String args[]) throws Exception {
//模拟流文件及参数上传
// testStreamUpload();
//httpClient模拟文件上传
testFileParamUpload();
//httpClient模拟发送json对象,用JSONObject接收
testJSONObjectUpload();
}
/**
* httpClient模拟文件上传
*/
static void testFileParamUpload() {
String url = "http://127.0.0.1:8090/kty/test/receiveHttpClientWithFile";
//json字符串,模拟了一个,传图片名字吧
Map param = new HashMap<>();
param.put("paramString", "i'm paramString!");
param.put("paramJSONObject", getJsonObj().toString());
param.put("paramJSONArray", getJsonArray().toString());
doPostFileAndParam(url, getFileList(), param);
}
/**
* 测试发送json对象并用json对象接收
*/
static void testJSONObjectUpload(){
String url = "http://127.0.0.1:8090/kty/test/receiveHttpClientJSONObject";
doPostJSONObject(url, getJsonObj(), getJsonArray());
}
文件和参数的 发送 和 接收 ,接收的时候要对应key value
testFileParamUpload
发送 httpClient 请求:
/**
* httpclient
* 发送文件和部分参数
*
* @return
*/
public static String doPostFileAndParam(String url, List> fileList, Map param) {
String result = "";
//新建一个httpclient
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
//新建一个Post请求
HttpPost httppost = new HttpPost(url);
//新建文件对象
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
ContentType contentType = ContentType.create("text/plain", "UTF-8");
//添加参数的时候,可以都使用addPart,然后new一个对象StringBody、FileBody、BinaryBody等
reqEntity
//设置编码,这两个一定要加,不然文件的文件名是中文就会乱码
.setCharset(Charset.forName("utf-8"))
//默认是STRICT模式,用这个就不能使用自定义的编码了
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)//也可以使用reqEntity.setLaxMode();具体的可以查看MultipartEntityBuilder类
//这个方法其实就是addPart(name, new StringBody(text, contentType));
.addTextBody("paramString", param.get("paramString").toString())
//textbody传送的都是String类型,所以接收只能用string接收,接收后转成json对象就可以了(后面一种方法直接可以用JSONObject接收,不论参数名)
.addTextBody("paramJSONObject", param.get("paramJSONObject").toString(), ContentType.APPLICATION_JSON)
.addTextBody("paramJSONArray", param.get("paramJSONArray").toString(), ContentType.APPLICATION_JSON)
//如果contentType不够用,可以自己定义
.addPart("paramPart", new StringBody("addPart你好", contentType));
//拼接文件类型
for (Map elem : fileList) {//拼接参数
String location = elem.get("location").toString();
String fileName = elem.get("fileName").toString();
System.out.println(fileName);
File file = new File(location);
//添加二进制内容,这个方法可以放流进去,也可以放文件对象进去,很方便
InputStream fileStream = new FileInputStream(file);
reqEntity.addBinaryBody("file", fileStream, ContentType.APPLICATION_OCTET_STREAM, fileName);
//文件的Contenttype貌似只要合理就行,流、form_data、或者干脆不填
// reqEntity.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, fileName);
//也可以用addPart添加
// reqEntity.addPart("file", new FileBody(file));
}
//将数据设置到post请求里
httppost.setEntity(reqEntity.build());
//执行提交
System.err.println("执行请求:" + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
//获得返回参数
InputStream is = response.getEntity().getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = in.readLine()) != null) {
buffer.append(line);
}
result = buffer.toString();
System.out.println("收到的返回:" + result);
//关闭返回
response.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭httpclient
httpclient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
接收:
/**
* httpclient 接收文件
* 文件需要从request里解析,可以自己手动解析,也可以像我这样直接用multirequest接收,然后用getFiles就能拿到文件
* 其他参数String类型
*
* @return
* @RequestBody 加了这个才能区分,不然默认都是String的key value格式,会报mismatch arguments
*/
@PostMapping("/receiveHttpClientWithFile")
public String receiveHttpClientWithFile(
MultipartHttpServletRequest multiRequest, String paramString, String paramPart,
String paramJSONObject, String paramJSONArray) {
String result = "成功收到请求";
System.out.println("收到请求,开始执行");
System.out.println("paramString===" + paramString);
System.out.println("paramPart===" + paramPart);
//这里就可以解析string为json对象
System.out.println("paramJSONObject===" + paramJSONObject);
JSONObject resJsonObj = JSONObject.fromObject(paramJSONObject);
System.out.println("json对象里的第一个元素token===" + resJsonObj.get("token"));
//这里就可以解析string为jsonarray数组
System.out.println("paramJSONArray===" + paramJSONArray);
JSONArray resJsonArray = JSONArray.fromObject(paramJSONArray);
System.out.println(resJsonArray.get(1));
List fileList = multiRequest.getFiles("file");
for (MultipartFile elem : fileList) {
System.out.println(elem.getOriginalFilename());
System.out.println("file===" + elem.getOriginalFilename() + "--" + elem.getSize() + elem.getContentType());
}
return result;
}
请求输出:
接收输出:
json对象的 发送 和 接收 ,接收方用 @RequestBody,无视对应key
testJSONObjectUpload()
发送 httpClient :
/**
* httpclient
* 发送json对象
* StringEntity可以直接用JSONObject接收
*
* @return
*/
public static String doPostJSONObject(String url, JSONObject jsonObject, JSONArray jsonArray) {
String result = "";
//新建一个httpclient
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
//新建一个Post请求
HttpPost httppost = new HttpPost(url);
//新建json对象
StringEntity stringEntity = new StringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON);
// StringEntity stringEntity = new StringEntity(jsonArray.toJSONString(), ContentType.APPLICATION_JSON);
//将数据设置到post请求里
httppost.setEntity(stringEntity);
//执行提交
System.err.println("执行请求:" + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
//获得返回参数
InputStream is = response.getEntity().getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = in.readLine()) != null) {
buffer.append(line);
}
result = buffer.toString();
System.out.println("收到的返回:" + result);
//关闭返回
response.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭httpclient
httpclient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
接收:
/**
* httpclient 接收json对象
*
* @return
*/
@PostMapping("/receiveHttpClientJSONObject")
public String receiveHttpClientJSONObject(@RequestBody JSONObject param) {
String result = "成功收到请求";
System.out.println("收到请求,开始执行");
System.out.println("param===" + param);
System.out.println("json对象里的第一个元素token===" + param.get("token"));
return result;
}
发送方控制台打印:
接收方控制台打印:
————————————————————————————————————————
综上,代码原文链接:https://blog.csdn.net/akxj2022/article/details/88691698
————————————————————————————————————————