【Java HTTP】http-request库使用
0. 前言
在弄钉钉机器人时需要在java程序中发起http请求,以前只在前端发起过http请求。所以就 总结下java是如何发送http请求的。
现在对java io还不是很熟,先使用第三方库。常见的有Spring家族,Apache家族的,还有OKHTTP。然后我在搜索第三方库的时候发现了一篇文章JAVA http请求工具类http-request。这篇文章推荐http-request这个库,可它的内容可真是劝退使用这个库 。
http-request库最后一次更新是2015年
1. http-request
1. 不携带任何参数的GET请求
服务端
@GetMapping("doGetByNull")
public String doGetByNull() {
return "这是不携带参数的【GET】请求";
}
工具类【HttpUtils】
public static void doGetByNull(String url) {
String body = HttpRequest.get(url, true).body();
log.info("doGetByNull:" + body);
}
测试类
@Test
void doGetByNull() {
HttpUtils.doGetByNull(URL + "doGetByNull");
}
结果
doGetByNull:这是不携带参数的【GET】请求
2. URL带参的GET请求
服务端
@GetMapping("doGetByUrl/{param}")
public String doGetByUrl(@PathVariable("param") String param) {
return "这是【URL带参】的【GET】请求,参数是【" + param + "】";
}
工具类【HttpUtils】
和上面用的是用的是同一个方法。
测试类
@Test
void doGetByUrl() {
HttpUtils.doGetByNull(URL + "doGetByUrl/苹果派");
}
结果
doGetByNull:这是【URL带参】的【GET】请求,参数是【苹果派】
这里是在get(url, true)
有true
这个参数才成功的。如果只是get(url)
则会出现
doGetByNull:<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</tit...
这是因为url上有中文的话,没有true参数的话不会解码,想更了解的话可以看看源码。
我一开始也不知道,而且还去issue上找了下,发现同样有老哥问issue#154,我又去看了下开头说的那片推荐文,但是没有介绍如何用url传参,更别说url上传中文出现错误的了。
可以看下请求是怎么样的。
可以看的出【苹果派】是没有被解析到url上的。
恰巧看到IDEA方法的参数提示有encode
,问题便解决了。
源码
public static HttpRequest get(CharSequence baseUrl, boolean encode, Object... params) {
String url = append(baseUrl, params);
return get((CharSequence)(encode ? encode(url) : url));
}
3. 携带Query参数的GET请求
服务端
@GetMapping("doGetByQuery")
public String doGetByQuery(String query1, String query2) {
return "这是携带【Query】参数的【GET】请求,参数是【" + query1 + "】和【" + query2 + "】";
}
工具类【HttpUtils】
public static void doGetByQuery(String url, Map data) {
String body = HttpRequest.get(url, data, true).body();
log.info("doGetByQuery:" + body);
}
测试类
@Test
void doGetByQuery() {
HashMap<String, String> data = new HashMap();
data.put("query1", "淡茶");
data.put("query2", "月亮");
HttpUtils.doGetByQuery(URL + "doGetByQuery", data);
}
结果
doGetByQuery:这是携带【Query】参数的【GET】请求,参数是【淡茶】和【月亮】
如何封装一个不确定query参数的GET请求,我一开始并不知道有get(CharSequence baseUrl, Map<?, ?> params, boolean encode)
这个方法,我就去看开头那片文章,告诉用form
这个方法,然而是失败的。失败数据就不放出来,就看生成的URL是怎么样的吧。
是一个POST请求,我不明白写这篇推荐文章的作者是否有实际操作过。
值得吐槽的是这个库的作者为什么重载不弄得有规律点。
get(CharSequence baseUrl, boolean encode, Object... params); get(CharSequence baseUrl, Map<?, ?> params, boolean encode)
我知道有一个可以传不定参数的方法,但是这样没法对它二次封装。我想这个库的作者应该会有提供一个方法可以用Map之类传参。所以我直接将 Object 换成了 Map,但是失败了。后面看下源码才知道。
4. 携带Query参数的POST请求
服务端
@PostMapping("doPostByQuery")
public String doPostByQuery(String query1, String query2) {
return "这是携带【Query】参数的【POST】请求,参数是【" + query1 + "】和【" + query2 + "】";
}
工具类【HttpUtils】
public static void doPostByQuery(String url, Map data) {
String body = HttpRequest.post(url).form(data).body();
log.info("doPostByQuery:" + body);
}
测试类
@Test
void doPostByQuery() {
HashMap<String, String> data = new HashMap();
data.put("query1", "fight");
data.put("query2", "喵~");
HttpUtils.doPostByQuery(URL + "doPostByQuery", data);
}
结果
doPostByQuery:这是携带【Query】参数的【POST】请求,参数是【fight】和【喵~】
这个倒是没什么问题,form参数和query参数都可以通过这个方式请求。
5. 携带Json参数的POST请求
服务端
@PostMapping("doPostByJson")
public String doPostByJson(@RequestBody TestDto testDto) {
return "这是携带【Json】参数的【POST】请求,参数是【" + testDto.toString() + "】";
}
工具类【HttpUtils】
public static void doPostByJson(String url, Object data) {
String json = JSON.toJSONString(data);
String body = HttpRequest.post(url)
.header(HttpRequest.HEADER_CONTENT_TYPE, HttpRequest.CONTENT_TYPE_JSON)
.send(json).body();
log.info("doPostByJson:" + body);
}
测试类
@Test
void doPostByJson() {
TestDto testDto = new TestDto("前辈", "好呀");
HttpUtils.doPostByJson(URL + "doPostByJson", testDto);
}
结果
doPostByJson:这是携带【Json】参数的【POST】请求,参数是【TestDto(field1=前辈, field2=好呀)】
携带JSON的POST请求,推荐这个库的作者没有介绍,官网也没介绍,去翻了下issue#110找到了。
6. 上传文件
服务端
@PostMapping("doPostByFile")
public String doPostByFile(@RequestParam("file") MultipartFile file) {
String filePath = "D:/file/";
String[] OriginalFilenameSplit = file.getOriginalFilename().split("\\.");
String fileName = UUID.randomUUID().toString().replace("-", "")
+ "."
+ OriginalFilenameSplit[OriginalFilenameSplit.length - 1];
File dest = new File(filePath + fileName);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
file.transferTo(dest);
return "上传成功";
} catch (IOException e) {
e.printStackTrace();
}
return "上传失败";
}
工具类【HttpU tils】
public static void doPostByFile(String url, Map<String, File> fileMap) {
HttpRequest request = HttpRequest.post(url);
for (String key : fileMap.keySet()) {
request.part(key, fileMap.get(key).getName(), fileMap.get(key));
}
log.info("doPostByFile:" + request.body());
}
测试类
@Test
void doPostByFile() {
File file = new File("C:\\Users\\Kzc19\\Desktop\\default.jpg");
Map<String, File> map = new HashMap();
map.put("file", file);
HttpUtils.doPostByFile(URL + "doPostByFile", map);
}
结果
doPostByFile:上传成功
这个地方按照官方例子是不行的,至少我是如此,且我在issue#73也发现有人通过官方例子失败的。但他们也给出了解决方法,用官方使用的那个方法的一个重载方法。
2. 结束
http-request这个库最后一次更新是在2015年,应该是已经没有维护了,在issue上的提问也没有回答,所以还是别使用这个库了。但是我觉得这个库就一个HttpRequest.java文件,非常的小巧,如果是学习java io,这个是一个很不错的学习 项目。
上面的源码上传到gitee上了。如有错误,请多指教。
转载自:https://juejin.cn/post/7045868668395192333