HttpClient 用法详细介绍

偏执的太偏执、 2023-06-27 15:57 65阅读 0赞

一、简介

超文本传输​​协议(HTTP)可能是当今Internet上使用的最重要的协议。Web服务,具有网络功能的设备以及网络计算的增长继续将HTTP协议的作用扩展到用户驱动的Web浏览器之外,同时增加了需要HTTP支持的应用程序的数量。尽管java.net 软件包提供了用于通过HTTP访问资源的基本功能,但它并未提供许多应用程序所需的全部灵活性或功能。Jakarta Commons HttpClient 组件试图通过提供高效,最新且功能丰富的程序包来实现此空白,以实现最新HTTP标准和建议的客户端。

Commons HttpClient项目现已停产,并且不再开发。它已被其HttpClient和HttpCore模块中的Apache HttpComponents项目取代。

二、项目搭建

tips:本项目案例是基于SpringBoot+SpringDataJPA环境搭建的

2.1 导入依赖:

  1. <dependencies>
  2. <!-- web场景 -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-web</artifactId>
  6. </dependency>
  7. <!-- jpa场景 -->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-data-jpa</artifactId>
  11. </dependency>
  12. <!-- mysql驱动 -->
  13. <dependency>
  14. <groupId>mysql</groupId>
  15. <artifactId>mysql-connector-java</artifactId>
  16. <version>8.0.18</version>
  17. </dependency>
  18. <!-- 单元测试 -->
  19. <dependency>
  20. <groupId>org.springframework.boot</groupId>
  21. <artifactId>spring-boot-starter-test</artifactId>
  22. <scope>test</scope>
  23. </dependency>
  24. <!-- HttpClient的依赖(httpmime依赖包含了httpclient以及httpcore) -->
  25. <dependency>
  26. <groupId>org.apache.httpcomponents</groupId>
  27. <artifactId>httpmime</artifactId>
  28. </dependency>
  29. <!-- 早期引入如下两个依赖 -->
  30. <!-- <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> -->
  31. <!-- 文件上传下载 -->
  32. <dependency>
  33. <groupId>commons-fileupload</groupId>
  34. <artifactId>commons-fileupload</artifactId>
  35. <version>1.3.3</version>
  36. </dependency>
  37. </dependencies>

2.2 application.properties:

  1. server.port=8080
  2. # 数据源配置
  3. spring.datasource.username=root
  4. spring.datasource.password=admin
  5. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  6. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2b8
  7. # jpa配置
  8. spring.jpa.show-sql=true
  9. spring.jpa.database=mysql

2.3 实体类:

  1. @Entity
  2. @Table(name = "user")
  3. public class User implements Serializable {
  4. @Id
  5. @GeneratedValue(strategy = GenerationType.IDENTITY)
  6. private Integer id;
  7. @Column
  8. private String username;
  9. @Column
  10. private Date birthday;
  11. @Column
  12. private String pic;
  13. // 省略get/set....
  14. }

2.4 dao:

  1. public interface UserDao extends JpaRepository<User,Integer> {
  2. }

2.5 controller:

  1. @RestController
  2. @RequestMapping("/user")
  3. public class UserController {
  4. @Autowired
  5. private UserDao userDao;
  6. /** * 添加用户 * @param user * @return * @throws Exception */
  7. @PostMapping
  8. public Map save(@RequestBody User user) throws Exception {
  9. user.setBirthday(new Date());
  10. userDao.save(user);
  11. Map returnMap = new HashMap<>();
  12. returnMap.put("message", "添加成功");
  13. return returnMap;
  14. }
  15. /** * 删除用户 * @param id * @return */
  16. @DeleteMapping("/{id}")
  17. public Map delete(@PathVariable Integer id) {
  18. userDao.deleteById(id);
  19. Map returnMap = new HashMap<>();
  20. returnMap.put("message", "删除成功");
  21. return returnMap;
  22. }
  23. /** * 修改用户 * @param id * @param user * @return */
  24. @PutMapping("/{id}")
  25. public Map update(@PathVariable Integer id, @RequestBody User user) {
  26. user.setId(id);
  27. userDao.save(user);
  28. Map returnMap = new HashMap<>();
  29. returnMap.put("message", "修改成功");
  30. return returnMap;
  31. }
  32. /** * 根据id查询用户 * @param id * @return */
  33. @GetMapping("/{id}")
  34. public User findById(@PathVariable Integer id) {
  35. return userDao.findById(id).get();
  36. }
  37. /** * 查询全部用户 * @return */
  38. @GetMapping
  39. public List<User> findAll() {
  40. return userDao.findAll();
  41. }
  42. /** * 上传头像 * * @param pic * @param username * @return * @throws Exception */
  43. @PostMapping("/upload")
  44. // 如果上传了多个文件使用:List<MultipartFile> pic
  45. public Map upload(MultipartFile pic, String username) throws Exception {
  46. pic.transferTo(new File("D:\\", UUID.randomUUID().toString() + ".png"));
  47. Map returnMap = new HashMap<>();
  48. returnMap.put("message", "上传成功");
  49. returnMap.put("data", username);
  50. return returnMap;
  51. }
  52. }

2.6 启动类:

  1. @SpringBootApplication
  2. public class HttpclientApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(HttpclientApplication.class, args);
  5. }
  6. }

数据库脚本如下:

  1. CREATE TABLE `user` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  4. `birthday` datetime(0) NULL DEFAULT NULL,
  5. `pic` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  6. PRIMARY KEY (`id`) USING BTREE
  7. ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

本人已亲测,controller所有接口均可用。大家可以跟我一样,先把环境搭建好

三、HttpClient快速入门

3.1 Get 请求

3.1.1 普通Get请求

  1. @Test
  2. public void test1() throws Exception{
  3. // 获取HttpClient实例
  4. CloseableHttpClient httpClient = HttpClients.createDefault();
  5. // 创建一个HttpGet请求
  6. HttpGet httpGet = new HttpGet("http://localhost:8080/user");
  7. // 发送请求,获取响应结果
  8. CloseableHttpResponse response = httpClient.execute(httpGet);
  9. // 获取响应实体
  10. HttpEntity responseEntity = response.getEntity();
  11. System.out.println("响应状态: " + response.getStatusLine());
  12. if (responseEntity != null) {
  13. System.out.println("响应内容长度为:" + responseEntity.getContentLength());
  14. System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
  15. }
  16. }

在这里插入图片描述

3.1.2 Get请求带参数

  • 请求代码:

    @Test
    public void test2() throws Exception {

    1. // 获取HttpClient实例
    2. CloseableHttpClient httpClient = HttpClients.createDefault();
    3. // 请求参数
    4. StringBuilder params = new StringBuilder();
    5. params.append("?");
    6. // 字符数据最好encoding一下;这样一来,某些特殊字符才能传过去(如:username就是"&",不encoding的话,解析时,会认为要拼接下一个参数username就为空)
    7. params.append("username=" + URLEncoder.encode("admin", "UTF8"));
    8. HttpGet httpGet = new HttpGet("http://localhost:8080/user/testGet" + params);
    9. // 发送请求,获取响应结果
    10. CloseableHttpResponse response = httpClient.execute(httpGet);
    11. // 获取响应实体
    12. HttpEntity responseEntity = response.getEntity();
    13. System.out.println("响应状态: " + response.getStatusLine());
    14. if (responseEntity != null) {
    15. System.out.println("响应内容长度为:" + responseEntity.getContentLength());
    16. System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    17. }

    }

  • 新增接口:

    @GetMapping(“/testGet”)
    public Map testGet(String username) throws Exception{

    1. Map returnMap = new HashMap<>();
    2. returnMap.put("message", "请求成功");
    3. returnMap.put("data", username);
    4. return returnMap;

    }

3.1.3 GET请求使用URI方式

使用URIBuilder()来构建一个uri对象用于传递参数使用。

URIBuilder()中有如下方法

  • setParameters(List<NameValuePair> params):用于构建多个键值对,使用List,单个NameValuePair用于封装一个键值对
  • setParameter(String key,String val):自己手动添加键值对

    // GET请求(使用URI获取HttpGet)
    @Test
    public void test3() throws Exception {

    1. // 获取HttpClient实例
    2. CloseableHttpClient httpClient = HttpClients.createDefault();
    3. // 将参数放入键值对类NameValuePair中,再放入集合中
    4. List<NameValuePair> params = new ArrayList<>();
    5. params.add(new BasicNameValuePair("username", "admin"));
    6. // 设置uri信息,并将参数集合放入uri;
    7. // 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
    8. URI uri = new URIBuilder().setScheme("http").setHost("localhost")
    9. .setPort(8080).setPath("/user/testGet")
    10. .setParameters(params).build();
    11. HttpGet httpGet = new HttpGet(uri);
    12. print(httpClient, httpGet);

    }

3.1.4 抽取打印方法

  1. /** * 抽取打印方法 * * @param httpClient * @param http * @throws Exception */
  2. private void print(CloseableHttpClient httpClient, HttpRequestBase http) throws Exception {
  3. // 发送请求,获取响应结果
  4. CloseableHttpResponse response = httpClient.execute(http);
  5. // 获取响应实体
  6. HttpEntity responseEntity = response.getEntity();
  7. System.out.println("响应状态: " + response.getStatusLine());
  8. if (responseEntity != null) {
  9. System.out.println("响应内容长度为:" + responseEntity.getContentLength());
  10. // 设置响应内容的编码(默认为UTF8)
  11. System.out.println("响应内容为:" + EntityUtils.toString(responseEntity, "UTF8"));
  12. }
  13. response.close();
  14. httpClient.close();
  15. }

3.2 Post请求

3.2.1 普通Post请求

  • 请求代码:

    @Test
    public void test4() throws Exception {

    1. // 获取HttpClient实例
    2. CloseableHttpClient httpClient = HttpClients.createDefault();
    3. HttpPost httpPost = new HttpPost("http://localhost:8080/user/testPost");
    4. print(httpClient, httpPost);

    }

  • 请求接口:

    @PostMapping(“/testPost”)
    public Map testPost() throws Exception {

    1. Map returnMap = new HashMap<>();
    2. returnMap.put("message", "普通方式post请求成功");
    3. return returnMap;

    }

3.2.2 Post请求带参数

  • 请求代码:

    @Test
    public void test5() throws Exception {

    1. // 获取HttpClient实例
    2. CloseableHttpClient httpClient = HttpClients.createDefault();
    3. HttpPost httpPost = new HttpPost("http://localhost:8080/user/testPost?username=admin");
    4. print(httpClient, httpPost);

    }

  • 新增接口

    @PostMapping(“/testPost2”)
    public Map testPost2(String username) throws Exception {

    1. Map returnMap = new HashMap<>();
    2. returnMap.put("message", "普通方式post请求成功");
    3. returnMap.put("data", username);
    4. return returnMap;

    }

3.2.3 Post请求提交对象

  1. @Test
  2. public void test6() throws Exception {
  3. // 获取HttpClient实例
  4. CloseableHttpClient httpClient = HttpClients.createDefault();
  5. User user=new User();
  6. user.setUsername("王五");
  7. // json转换工具
  8. ObjectMapper om = new ObjectMapper();
  9. StringEntity entity = new StringEntity(om.writeValueAsString(user), "utf-8");
  10. HttpPost httpPost = new HttpPost("http://localhost:8080/user");
  11. // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
  12. httpPost.setEntity(entity);
  13. // 设置请求头
  14. httpPost.setHeader("Content-Type", "application/json;charset=utf8");
  15. httpClient.execute(httpPost);
  16. print(httpClient, httpPost);
  17. }

3.2.4 Post请求对象+参数

  • 请求代码:

    @Test
    public void test7() throws Exception {

    1. // 获取HttpClient实例
    2. CloseableHttpClient httpClient = HttpClients.createDefault();
    3. User user=new User();
    4. user.setUsername("赵六");
    5. // json转换工具
    6. ObjectMapper om = new ObjectMapper();
    7. StringEntity entity = new StringEntity(om.writeValueAsString(user), "utf-8");
    8. // 构建uri
    9. URI uri = new URIBuilder().setScheme("http").setHost("localhost")
    10. .setPort(8080).setPath("/user/testPost")
    11. .setParameter("flag", "测试post请求带参哦!") //使用setParameter设置单个参数
    12. .build();
    13. HttpPost httpPost = new HttpPost(uri);
    14. // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
    15. httpPost.setEntity(entity);
    16. // 设置请求头
    17. httpPost.setHeader("Content-Type", "application/json;charset=utf8");
    18. httpClient.execute(httpPost);
    19. print(httpClient, httpPost);

    }

  • 新增接口:

    @PostMapping(“/testPost3”)
    public Map testPost3(@RequestBody User user, String flag) throws Exception {

    1. user.setBirthday(new Date());
    2. userDao.save(user);
    3. Map returnMap = new HashMap<>();
    4. returnMap.put("message", "请求testPost3成功");
    5. returnMap.put("data", flag);
    6. return returnMap;

    }

3.3 Put请求

  1. @Test
  2. public void test8() throws Exception {
  3. // 获取HttpClient实例
  4. CloseableHttpClient httpClient = HttpClients.createDefault();
  5. User user=new User();
  6. user.setUsername("管理员");
  7. ObjectMapper om=new ObjectMapper();
  8. String userStr = om.writeValueAsString(user);
  9. // 构建实体
  10. StringEntity entity = new StringEntity(userStr, StandardCharsets.UTF_8);
  11. HttpPut httpPut = new HttpPut("http://localhost:8080/user/12");
  12. // 设置请求头
  13. httpPut.setHeader("Content-Type", "application/json;charset=utf8");
  14. httpPut.setEntity(entity);
  15. httpClient.execute(httpPut);
  16. print(httpClient,httpPut);
  17. }

3.4 Delete请求

  1. @Test
  2. public void test9() throws Exception {
  3. // 获取HttpClient实例
  4. CloseableHttpClient httpClient = HttpClients.createDefault();
  5. HttpDelete httpDelete = new HttpDelete("http://localhost:8080/user/12");
  6. httpClient.execute(httpDelete);
  7. print(httpClient,httpDelete);
  8. }

四、特殊类型请求

4.1 模拟表单提交

  • 4.1.1 请求代码:

    @Test
    public void test10() throws Exception {

    1. // 获取HttpClient实例
    2. CloseableHttpClient httpClient = HttpClients.createDefault();
    3. HttpPost httpPost = new HttpPost("http://localhost:8080/user/testForm");
    4. // 设置请求头
    5. httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
    6. List<BasicNameValuePair> params = new ArrayList<>();
    7. params.add(new BasicNameValuePair("id","100"));
    8. params.add(new BasicNameValuePair("username","张三"));
    9. // 这里不要传递birthday,后台需要定义converter,做类型转换(String->Date),你们有兴趣自己去玩,也不难

    // params.add(new BasicNameValuePair(“birthday”,new SimpleDateFormat(“yyyy-MM-dd”).format(new Date())));

    1. params.add(new BasicNameValuePair("pic","https://www.baidu.com/favicon.ico"));
    2. // 构建一个虚拟表单,并设置参数
    3. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params,StandardCharsets.UTF_8);
    4. // 设置请求实体
    5. httpPost.setEntity(entity);
    6. // 发送请求
    7. httpClient.execute(httpPost);
    8. print(httpClient, httpPost);

    }

  • 4.1.2 新增接口:

    /* 测试表单传输 @param user @return @throws Exception /
    @PostMapping(“/testForm”)
    public Map testPost3(User user) throws Exception {

    1. Map returnMap = new HashMap<>();
    2. returnMap.put("message", "请求testForm成功");
    3. returnMap.put("data", user);
    4. return returnMap;

    }

4.2 上传文件

注:

  1. <dependency>
  2. <groupId>org.apache.httpcomponents</groupId>
  3. <artifactId>httpmime</artifactId>
  4. </dependency>
  5. @Test
  6. public void test11() throws Exception {
  7. // 获取HttpClient实例
  8. CloseableHttpClient httpClient = HttpClients.createDefault();
  9. MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
  10. // 可以添加多个图片(name保持一致就行,后台使用List<MultipartFile> pic接收)
  11. // multipartEntityBuilder.addBinaryBody("pic",new File("D:\\10.png"));
  12. multipartEntityBuilder.addBinaryBody("pic",new File("D:\\11.png"));
  13. // 携带文本参数
  14. multipartEntityBuilder.addTextBody("username","管理员", ContentType.create("text/plain",StandardCharsets.UTF_8));
  15. // 装换为HttpEntity
  16. HttpEntity entity = multipartEntityBuilder.build();
  17. HttpPost httpPost = new HttpPost("http://localhost:8080/user/upload");
  18. httpPost.setEntity(entity);
  19. print(httpClient,httpPost);
  20. }

4.3 传递数据流

  • 4.3.1 请求代码:

    // 发送数据流
    @Test
    public void test12() throws Exception {

    1. // 获取HttpClient实例
    2. CloseableHttpClient httpClient = HttpClients.createDefault();
    3. InputStream is = new ByteArrayInputStream("admin".getBytes());
    4. // 构建数据流实体
    5. InputStreamEntity entity = new InputStreamEntity(is);
    6. HttpPost httpPost = new HttpPost("http://localhost:8080/user/testStream");
    7. httpPost.setEntity(entity);
    8. // 发送请求
    9. httpClient.execute(httpPost);
    10. print(httpClient,httpPost);

    }

  • 4.3.2 新增接口:

    /* 测试数据流传输 @param is @return @throws Exception */
    @PostMapping(value = “/testStream”)
    public Map testStream(InputStream is) throws Exception {

    1. // 接受前端传递的数据
    2. String str = new BufferedReader(new InputStreamReader(is)).readLine();
    3. Map returnMap = new HashMap<>();
    4. returnMap.put("message", "testStream");
    5. returnMap.put("data", str);
    6. return returnMap;

    }

发表评论

表情:
评论列表 (有 0 条评论,65人围观)

还没有评论,来说两句吧...

相关阅读