HttpClient 用法详细介绍

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 HttpClient 用法详细介绍,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、简介

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

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

二、项目搭建

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

2.1 导入依赖:

<dependencies>

    <!-- web场景 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- jpa场景 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- mysql驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.18</version>
    </dependency>

    <!-- 单元测试 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- HttpClient的依赖(httpmime依赖包含了httpclient以及httpcore) -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
    </dependency>

    <!-- 早期引入如下两个依赖 -->
<!--
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
    </dependency>
-->

    <!-- 文件上传下载 -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.3</version>
    </dependency>
</dependencies>

2.2 application.properties:

server.port=8080

# 数据源配置
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=GMT%2b8

# jpa配置
spring.jpa.show-sql=true
spring.jpa.database=mysql

2.3 实体类:

@Entity
@Table(name = "user")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column
    private String username;

    @Column
    private Date birthday;

    @Column
    private String pic;

	// 省略get/set....
}

2.4 dao:

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

2.5 controller:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserDao userDao;

    /**
     * 添加用户
     * @param user
     * @return
     * @throws Exception
     */
    @PostMapping
    public Map save(@RequestBody User user) throws Exception {
        user.setBirthday(new Date());
        userDao.save(user);
        Map returnMap = new HashMap<>();
        returnMap.put("message", "添加成功");

        return returnMap;
    }

    /**
     * 删除用户
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public Map delete(@PathVariable Integer id) {

        userDao.deleteById(id);

        Map returnMap = new HashMap<>();
        returnMap.put("message", "删除成功");
        return returnMap;
    }

    /**
     * 修改用户
     * @param id
     * @param user
     * @return
     */
    @PutMapping("/{id}")
    public Map update(@PathVariable Integer id, @RequestBody User user) {

        user.setId(id);
        userDao.save(user);

        Map returnMap = new HashMap<>();
        returnMap.put("message", "修改成功");
        return returnMap;
    }

    /**
     * 根据id查询用户
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public User findById(@PathVariable Integer id) {
        return userDao.findById(id).get();
    }

    /**
     * 查询全部用户
     * @return
     */
    @GetMapping
    public List<User> findAll() {
        return userDao.findAll();
    }

	/**
	 * 上传头像
	 *
	 * @param pic
	 * @param username
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/upload")
	// 如果上传了多个文件使用:List<MultipartFile> pic
	public Map upload(MultipartFile pic, String username) throws Exception {
	
	    pic.transferTo(new File("D:\\", UUID.randomUUID().toString() + ".png"));
	
	    Map returnMap = new HashMap<>();
	    returnMap.put("message", "上传成功");
	    returnMap.put("data", username);
	    return returnMap;
	}
}

2.6 启动类:

@SpringBootApplication
public class HttpclientApplication {

    public static void main(String[] args) {
        SpringApplication.run(HttpclientApplication.class, args);
    }

}

数据库脚本如下:

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

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

三、HttpClient快速入门

3.1 Get 请求

3.1.1 普通Get请求

@Test
public void test1() throws Exception{

    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    // 创建一个HttpGet请求
    HttpGet httpGet = new HttpGet("http://localhost:8080/user");

    // 发送请求,获取响应结果
    CloseableHttpResponse response = httpClient.execute(httpGet);

    // 获取响应实体
    HttpEntity responseEntity = response.getEntity();

    System.out.println("响应状态: " + response.getStatusLine());
    if (responseEntity != null) {
        System.out.println("响应内容长度为:" + responseEntity.getContentLength());
        System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    }
}

在这里插入图片描述

3.1.2 Get请求带参数

  • 请求代码:
@Test
public void test2() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    // 请求参数
    StringBuilder params = new StringBuilder();
    params.append("?");
    // 字符数据最好encoding一下;这样一来,某些特殊字符才能传过去(如:username就是"&",不encoding的话,解析时,会认为要拼接下一个参数username就为空)
    params.append("username=" + URLEncoder.encode("admin", "UTF8"));

    HttpGet httpGet = new HttpGet("http://localhost:8080/user/testGet" + params);

    // 发送请求,获取响应结果
    CloseableHttpResponse response = httpClient.execute(httpGet);

    // 获取响应实体
    HttpEntity responseEntity = response.getEntity();

    System.out.println("响应状态: " + response.getStatusLine());
    if (responseEntity != null) {
        System.out.println("响应内容长度为:" + responseEntity.getContentLength());
        System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
    }
}
  • 新增接口:
@GetMapping("/testGet")
public Map testGet(String username) throws Exception{

    Map returnMap = new HashMap<>();
    returnMap.put("message", "请求成功");
    returnMap.put("data", username);
    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 {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    // 将参数放入键值对类NameValuePair中,再放入集合中
    List<NameValuePair> params = new ArrayList<>();
    params.add(new BasicNameValuePair("username", "admin"));

    // 设置uri信息,并将参数集合放入uri;
    // 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
    URI uri = new URIBuilder().setScheme("http").setHost("localhost")
            .setPort(8080).setPath("/user/testGet")
            .setParameters(params).build();

    HttpGet httpGet = new HttpGet(uri);

    print(httpClient, httpGet);
}

3.1.4 抽取打印方法

/**
 * 抽取打印方法
 *
 * @param httpClient
 * @param http
 * @throws Exception
 */
private void print(CloseableHttpClient httpClient, HttpRequestBase http) throws Exception {
    // 发送请求,获取响应结果
    CloseableHttpResponse response = httpClient.execute(http);

    // 获取响应实体
    HttpEntity responseEntity = response.getEntity();

    System.out.println("响应状态: " + response.getStatusLine());
    if (responseEntity != null) {
        System.out.println("响应内容长度为:" + responseEntity.getContentLength());
		
		// 设置响应内容的编码(默认为UTF8)
        System.out.println("响应内容为:" + EntityUtils.toString(responseEntity, "UTF8"));
    }

    response.close();
    httpClient.close();
}

3.2 Post请求

3.2.1 普通Post请求

  • 请求代码:
@Test
public void test4() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("http://localhost:8080/user/testPost");

    print(httpClient, httpPost);

}
  • 请求接口:
@PostMapping("/testPost")
public Map testPost() throws Exception {

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

3.2.2 Post请求带参数

  • 请求代码:
@Test
public void test5() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("http://localhost:8080/user/testPost?username=admin");

    print(httpClient, httpPost);

}
  • 新增接口
@PostMapping("/testPost2")
public Map testPost2(String username) throws Exception {

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

3.2.3 Post请求提交对象

@Test
public void test6() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    User user=new User();
    user.setUsername("王五");

    // json转换工具
    ObjectMapper om = new ObjectMapper();
    StringEntity entity = new StringEntity(om.writeValueAsString(user), "utf-8");

    HttpPost httpPost = new HttpPost("http://localhost:8080/user");

    // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
    httpPost.setEntity(entity);

    // 设置请求头
    httpPost.setHeader("Content-Type", "application/json;charset=utf8");
    httpClient.execute(httpPost);

    print(httpClient, httpPost);

}

3.2.4 Post请求对象+参数

  • 请求代码:
@Test
public void test7() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    User user=new User();
    user.setUsername("赵六");

    // json转换工具
    ObjectMapper om = new ObjectMapper();
    StringEntity entity = new StringEntity(om.writeValueAsString(user), "utf-8");

    // 构建uri
    URI uri = new URIBuilder().setScheme("http").setHost("localhost")
            .setPort(8080).setPath("/user/testPost")
            .setParameter("flag", "测试post请求带参哦!")       //使用setParameter设置单个参数
            .build();

    HttpPost httpPost = new HttpPost(uri);

    // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
    httpPost.setEntity(entity);

    // 设置请求头
    httpPost.setHeader("Content-Type", "application/json;charset=utf8");
    httpClient.execute(httpPost);

    print(httpClient, httpPost);

}
  • 新增接口:
@PostMapping("/testPost3")
public Map testPost3(@RequestBody User user, String flag) throws Exception {
    user.setBirthday(new Date());
    userDao.save(user);
    Map returnMap = new HashMap<>();
    returnMap.put("message", "请求testPost3成功");
    returnMap.put("data", flag);

    return returnMap;
}

3.3 Put请求

@Test
public void test8() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    User user=new User();
    user.setUsername("管理员");

    ObjectMapper om=new ObjectMapper();
    String userStr = om.writeValueAsString(user);
    // 构建实体
    StringEntity entity = new StringEntity(userStr, StandardCharsets.UTF_8);

    HttpPut httpPut = new HttpPut("http://localhost:8080/user/12");

    // 设置请求头
    httpPut.setHeader("Content-Type", "application/json;charset=utf8");
    httpPut.setEntity(entity);

    httpClient.execute(httpPut);

    print(httpClient,httpPut);
}

3.4 Delete请求

@Test
public void test9() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    HttpDelete httpDelete = new HttpDelete("http://localhost:8080/user/12");

    httpClient.execute(httpDelete);

    print(httpClient,httpDelete);

}

四、特殊类型请求

4.1 模拟表单提交

  • 4.1.1 请求代码:
@Test
public void test10() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost("http://localhost:8080/user/testForm");

    // 设置请求头
    httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

    List<BasicNameValuePair> params = new ArrayList<>();
    params.add(new BasicNameValuePair("id","100"));
    params.add(new BasicNameValuePair("username","张三"));
    // 这里不要传递birthday,后台需要定义converter,做类型转换(String->Date),你们有兴趣自己去玩,也不难
//        params.add(new BasicNameValuePair("birthday",new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
    params.add(new BasicNameValuePair("pic","https://www.baidu.com/favicon.ico"));

    // 构建一个虚拟表单,并设置参数
    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params,StandardCharsets.UTF_8);

    // 设置请求实体
    httpPost.setEntity(entity);

    // 发送请求
    httpClient.execute(httpPost);

    print(httpClient, httpPost);

}
  • 4.1.2 新增接口:
/**
 * 测试表单传输
 * @param user
 * @return
 * @throws Exception
 */
@PostMapping("/testForm")
public Map testPost3(User user) throws Exception {
    Map returnMap = new HashMap<>();
    returnMap.put("message", "请求testForm成功");
    returnMap.put("data", user);

    return returnMap;
}

4.2 上传文件

注:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
</dependency>
@Test
public void test11() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();

    // 可以添加多个图片(name保持一致就行,后台使用List<MultipartFile> pic接收)
//        multipartEntityBuilder.addBinaryBody("pic",new File("D:\\10.png"));
    multipartEntityBuilder.addBinaryBody("pic",new File("D:\\11.png"));

    // 携带文本参数
    multipartEntityBuilder.addTextBody("username","管理员", ContentType.create("text/plain",StandardCharsets.UTF_8));

    // 装换为HttpEntity
    HttpEntity entity = multipartEntityBuilder.build();

    HttpPost httpPost = new HttpPost("http://localhost:8080/user/upload");

    httpPost.setEntity(entity);

    print(httpClient,httpPost);

}

4.3 传递数据流

  • 4.3.1 请求代码:
// 发送数据流
@Test
public void test12() throws Exception {
    // 获取HttpClient实例
    CloseableHttpClient httpClient = HttpClients.createDefault();

    InputStream is = new ByteArrayInputStream("admin".getBytes());

    // 构建数据流实体
    InputStreamEntity entity = new InputStreamEntity(is);

    HttpPost httpPost = new HttpPost("http://localhost:8080/user/testStream");

    httpPost.setEntity(entity);

    // 发送请求
    httpClient.execute(httpPost);

    print(httpClient,httpPost);

}
  • 4.3.2 新增接口:
/**
 * 测试数据流传输
 *
 * @param is
 * @return
 * @throws Exception
 */
@PostMapping(value = "/testStream")
public Map testStream(InputStream is) throws Exception {
    // 接受前端传递的数据
    String str = new BufferedReader(new InputStreamReader(is)).readLine();
    Map returnMap = new HashMap<>();
    returnMap.put("message", "testStream");
    returnMap.put("data", str);

    return returnMap;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131849.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!