好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java 使用 HttpClient 发送 GET请求和 POST请求

概述

日常工作中,我们经常会有发送 HTTP 网络请求的需求,概括下我们常见的发送 HTTP 请求的需求内容:

可以发送基本的 GET/POST/PUT/DELETE 等请求; HTTP请求,可以附带认证,包括基本的 用户名/密码 认证,以及 Bearer Token 认证; 请求可以自定义 超时时间; HTTP请求可以带参数,也可以不带参数; HTTP请求返回结果,可以直接传入一个 Class,这样结果就不用二次解析; 请求的路径可以是 url,也可以是 Uri;

针对以上常见的 HTTP 请求,在 HttpClient 的基础上做了二次封装,可以直接简单、高效地发送HTTP请求。

本文所使用的的 HttpClient 版本为 4.5.3,pom依赖如下:

?

1

2

3

4

5

< dependency >

     < groupId >org.apache.httpcomponents</ groupId >

     < artifactId >httpclient</ artifactId >

     < version >4.5.3</ version >

</ dependency >

认证方式

HTTP请求中,常用的认证方式包括:

用户名 + 密码 认证 Bearer Token 认证

其实这些认证的本质,都是通过在 HTTP Request Header 中,添加固定的参数,如下格式:

?

1

Authorization: token字符串

上面的Authorization 就是 HTTP Header 的 key,而 token字符串 就是具体的认证方式中需要传递的参数。

我们将所有的认证方式,都抽象为 Auth 类,并定义方法 getAuth 方法,由具体的子类去实现,返回自定义认证方式中所需要的token字符串。

基础认证Auth

?

1

2

3

4

public interface Auth {

 

     String getAuth();

}

用户名密码认证

BasicAuth,用于做用户名和密码认证,代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

public class BasicAuth implements Auth {

 

     private String username;

 

     private String password;

 

     public BasicAuth(String username, String password) {

         this .username = username;

         this .password = password;

     }

 

     @Override

     public String getAuth() {

         String auth = String.format( "%s:%s" , this .username, this .password);

 

         byte [] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));

         return "Basic " + new String(encodedAuth);

     }

}

Bearer Token 认证

BearerAuth,用于做 Bearer Token认证,代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

public class BearerAuth implements Auth {

 

     private String token;

 

     public BearerAuth(String token) {

         this .token = token;

     }

 

     @Override

     public String getAuth() {

         return "Bearer " + this .token;

     }

}

上面介绍了两种常用的认证方式,如果有其他的认证方式,实现 Auth 接口的 getAuth 方法即可。

这个 Auth 我们会在真正发送 HTTP 请求时用到。

配置超时

HttpClient中,通过 setDefaultRequestConfig 来设置请求的参数配置,包括请求超时时间等。

生成 RequestConfig

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

/**

  * 设置 HTTP 请求超时时间

  *

  * @param connectTimeout tcp 连接超时时间

  * @param readTimeout    读取数据超时时间

  * @return

  */

private RequestConfig getRequestConfig( int connectTimeout, int readTimeout) {

     return RequestConfig.custom()

             .setConnectTimeout(connectTimeout)

             .setConnectionRequestTimeout(connectTimeout)

             .setSocketTimeout(readTimeout)

             .build();

}

设置超时时间

?

1

2

3

HttpClientBuilder.create()

         .setDefaultRequestConfig(requestConfig)

         .build();

到这里,HttpClient所需要做的一些配置,基本就结束了,下面将展示完整的代码示例。

完整代码 HttpRequestClient

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

import com.google.gson.Gson;

import lombok.extern.slf4j.Slf4j;

import org.apache测试数据mons.lang3.StringUtils;

import org.apache.http.HttpHeaders;

import org.apache.http.HttpResponse;

import org.apache.http.client.HttpClient;

import org.apache.http.client.config.RequestConfig;

import org.apache.http.client.methods.RequestBuilder;

import org.apache.http.entity.ContentType;

import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.HttpClientBuilder;

import org.apache.http.util.EntityUtils;

import org.springframework.http.HttpMethod;

 

import java.io.IOException;

import java.net.URI;

import java.nio.charset.StandardCharsets;

import java.util.HashMap;

import java.util.Map;

 

/**

  * @author wxweven

  */

@Slf4j

public class HttpRequestClient {

 

     // 默认 连接/读取数据 超时时间都是 10s

     private static final int DEFAULT_CONNECT_TIMEOUT = 10_000;

     private static final int DEFAULT_READ_TIMEOUT = 10_000;

     private static final Gson GSON = new Gson();

 

     private Auth auth;

     private HttpClient httpClient;

 

     // 用户名密码认证,默认的超时时间(10s)

     public HttpRequestClient(String username, String password) {

         this (username, password,

                 DEFAULT_CONNECT_TIMEOUT,

                 DEFAULT_READ_TIMEOUT

         );

     }

 

     // 用户名密码认证,自定义超时时间

     public HttpRequestClient(String username, String password,

                                int connectTimeout, int readTimeout) {

 

         this .auth = new BasicAuth(username, password);

         this .httpClient = HttpClientBuilder.create()

                 .setDefaultRequestConfig(getRequestConfig(connectTimeout, readTimeout))

                 .build();

     }

 

     // BearerToken 认证,默认的超时时间(10s)

     public HttpRequestClient(String bearerToken) {

         this (bearerToken,

                 DEFAULT_CONNECT_TIMEOUT,

                 DEFAULT_READ_TIMEOUT

         );

     }

 

     // BearerToken 认证,自定义超时时间

     public HttpRequestClient(String bearerToken,

                                int connectTimeout, int readTimeout) {

 

         this .auth = new BearerAuth(bearerToken);

         this .httpClient = HttpClientBuilder.create()

                 .setDefaultRequestConfig(getRequestConfig(connectTimeout, readTimeout))

                 .build();

     }

 

     /**

      * 设置 HTTP 请求超时时间

      *

      * @param connectTimeout tcp 连接超时时间

      * @param readTimeout    读取数据超时时间

      * @return

      */

     private RequestConfig getRequestConfig( int connectTimeout, int readTimeout) {

         return RequestConfig.custom()

                 .setConnectTimeout(connectTimeout)

                 .setConnectionRequestTimeout(connectTimeout)

                 .setSocketTimeout(readTimeout)

                 .build();

     }

 

     /**

      * 发送 GET 请求,不带参数

      *

      * @param url

      * @return

      */

     public String doGet(String url) {

         return doGet(url, new HashMap<>());

     }

 

     /**

      * 发送 GET 请求,不带参数

      *

      * @param uri

      * @return

      */

     public String doGet(URI uri) {

         return doGet(uri, new HashMap<>());

     }

 

     /**

      * 发送 GET 请求,K-V 形式参数

      *

      * @param url

      * @param params

      * @return

      */

     public String doGet(String url, Map<String, String> params) {

         RequestBuilder reqBuilder = RequestBuilder.get(url);

         return doGet(reqBuilder, params);

     }

 

     /**

      * 发送 GET 请求,K-V 形式参数

      *

      * @param uri

      * @param params

      * @return

      */

     public String doGet(URI uri, Map<String, String> params) {

         RequestBuilder reqBuilder = RequestBuilder.get(uri);

         return doGet(reqBuilder, params);

     }

 

     public String doGet(RequestBuilder reqBuilder, Map<String, String> params) {

         reqBuilder.addHeader(HttpHeaders.AUTHORIZATION, auth.getAuth());

 

         for (Map.Entry<String, String> entry : params.entrySet()) {

             reqBuilder.addParameter(entry.getKey(), entry.getValue());

         }

 

         try {

             HttpResponse resp = httpClient.execute(reqBuilder.build());

             return EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);

         } catch (IOException e) {

             log.error( "doGet 异常: reqBuilder={}, params={}" , reqBuilder, params, e);

             return null ;

         }

     }

 

     /***

      * 发送 GET 请求,不带参数,返回指定类型的 class

      * @param url 请求的 url

      * @param responseType 返回类型

      * @param <T>

      * @return

      */

     public <T> T getForObject(String url, Class<T> responseType) {

         RequestBuilder reqBuilder = RequestBuilder.get(url);

         return getForObject(reqBuilder, responseType);

     }

 

     /***

      * 发送 GET 请求,不带参数,返回指定类型的 class

      * @param uri 请求的 uri

      * @param responseType 返回类型

      * @param <T>

      * @return

      */

     public <T> T getForObject(URI uri, Class<T> responseType) {

         RequestBuilder reqBuilder = RequestBuilder.get(uri);

         return getForObject(reqBuilder, responseType);

     }

 

     public <T> T getForObject(RequestBuilder reqBuilder, Class<T> responseType) {

         reqBuilder.addHeader(HttpHeaders.AUTHORIZATION, auth.getAuth());

 

         try {

             HttpResponse resp = httpClient.execute(reqBuilder.build());

             String result = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);

 

             return GSON.fromJson(result, responseType);

         } catch (IOException e) {

             log.error( "getForObject 异常: reqBuilder={}, responseType={}" , reqBuilder, responseType, e);

             return null ;

         }

     }

 

     /**

      * 发送 POST 请求,JSON 形式

      *

      * @param url

      * @param json json字符串

      * @return

      */

     public String doPost(String url, String json) {

         try {

             HttpResponse resp = this .exchange(HttpMethod.POST, url, json);

             return EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);

         } catch (IOException e) {

             log.error( "doPost 异常: url={}, json={}" , url, json, e);

             return null ;

         }

     }

 

     /**

      * 发送 POST 请求,JSON 形式,返回 HttpResponse

      *

      * @param url

      * @param json json字符串

      * @return

      */

     public HttpResponse doPostResp(String url, String json) {

         return this .exchange(HttpMethod.POST, url, json);

     }

 

     /**

      * 发送 PUT 请求,JSON 形式

      *

      * @param url

      * @param json json字符串

      * @return

      */

     public HttpResponse doPut(String url, String json) {

         return this .exchange(HttpMethod.PUT, url, json);

     }

 

     /**

      * 发送 PUT 请求,JSON 形式

      *

      * @param url

      * @param json json字符串

      * @return

      */

     public HttpResponse doDelete(String url, String json) {

         return this .exchange(HttpMethod.DELETE, url, json);

     }

 

     public HttpResponse exchange(HttpMethod method, String url, String json) {

         RequestBuilder reqBuilder = RequestBuilder.create(method.toString())

                 .setUri(url)

                 .addHeader(HttpHeaders.AUTHORIZATION, auth.getAuth())

                 .addHeader( "Accept" , ContentType.APPLICATION_JSON.toString())

                 .addHeader( "Content-type" , ContentType.APPLICATION_JSON.toString());

 

         if (StringUtils.isNotBlank(json)) {

             reqBuilder.setEntity( new StringEntity(json, ContentType.APPLICATION_JSON));

         }

 

         try {

             return httpClient.execute(reqBuilder.build());

         } catch (IOException e) {

             log.error( "doPost 异常: url={}, json={}" , url, json, e);

             return null ;

         }

     }

}

到此这篇关于Java 使用 HttpClient 发送 GET请求和 POST请求的文章就介绍到这了,更多相关Java HttpClient GET请求和 POST请求内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

原文链接:https://juejin.cn/post/6998826369819869215

查看更多关于Java 使用 HttpClient 发送 GET请求和 POST请求的详细内容...

  阅读:36次