版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vbirdbest/article/details/83023338
在开发中经常会遇到调用第三方的接口,这里介绍一下在spring boot中如何使用httpclient来发送get和post请求。
- 引入依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
- application.properties
#最大连接数
http.maxTotal = 100
#并发数
http.defaultMaxPerRoute = 20
#创建连接的最长时间
http.connectTimeout=1000
#从连接池中获取到连接的最长时间
http.connectionRequestTimeout=500
#数据传输的最长时间
http.socketTimeout=10000
http.validateAfterInactivity=1000
- Configuration
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpClientConfiguration {
@Value("${http.maxTotal}")
private Integer maxTotal;
@Value("${http.defaultMaxPerRoute}")
private Integer defaultMaxPerRoute;
@Value("${http.connectTimeout}")
private Integer connectTimeout;
@Value("${http.connectionRequestTimeout}")
private Integer connectionRequestTimeout;
@Value("${http.socketTimeout}")
private Integer socketTimeout;
@Value("${http.validateAfterInactivity}")
private Integer validateAfterInactivity;
@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager(){
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(maxTotal);
connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
connectionManager.setValidateAfterInactivity(validateAfterInactivity);
return connectionManager;
}
@Bean
public HttpClientBuilder httpClientBuilder(PoolingHttpClientConnectionManager poolingHttpClientConnectionManager){
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
return httpClientBuilder;
}
@Bean
public CloseableHttpClient closeableHttpClient(HttpClientBuilder httpClientBuilder){
return httpClientBuilder.build();
}
@Bean
public RequestConfig.Builder builder(){
RequestConfig.Builder builder = RequestConfig.custom();
return builder.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout)
.setSocketTimeout(socketTimeout);
}
@Bean
public RequestConfig requestConfig(RequestConfig.Builder builder){
return builder.build();
}
}
- HttpClient
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class HttpClient {
/** 默认字符集 */
public static final String DEFAULT_CHARSET = "UTF-8";
@Autowired
private CloseableHttpClient closeableHttpClient;
@Autowired
private RequestConfig config;
/**
* 用于JSON格式的API调用
* @param url url地址
* @param requestParameter 请求参数
* @param clazz 接口返回值的类型
* @return
* @throws Exception
*/
public <T> T doGet(String url, Map<String, Object> requestParameter, Class<T> clazz) throws Exception {
String responseJson = this.doGet(url, requestParameter);
T response = JSONObject.parseObject(responseJson, clazz);
return response;
}
public String doGet(String url, Map<String, Object> requestParameter) throws Exception {
URIBuilder uriBuilder = new URIBuilder(url);
if (requestParameter != null) {
for (Map.Entry<String, Object> entry : requestParameter.entrySet()) {
uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
}
}
return this.doGet(uriBuilder.build().toString());
}
public String doGet(String url) throws Exception {
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(config);
httpGet.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
CloseableHttpResponse response = this.closeableHttpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
throw new Exception("api request exception, http reponse code:" + statusCode);
}
return EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
}
public <T> T doPost(String url, Map<String, Object> requestParameter, Class<T> clazz) throws Exception {
HttpResponse httpResponse = this.doPost(url, requestParameter);
int statusCode = httpResponse.getCode();
if (statusCode != HttpStatus.SC_OK) {
throw new Exception("api request exception, http reponse code:" + statusCode);
}
T response = JSONObject.parseObject(httpResponse.getBody(), clazz);
return response;
}
public HttpResponse doPost(String url, Map<String, Object> requestParameter) throws Exception {
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(config);
httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
if (requestParameter != null) {
String requestBody = JSONObject.toJSONString(requestParameter);
StringEntity postEntity = new StringEntity(requestBody, "UTF-8");
httpPost.setEntity(postEntity);
}
CloseableHttpResponse response = this.closeableHttpClient.execute(httpPost);
// 对请求的响应进行简单的包装成自定义的类型
return new HttpResponse(response.getStatusLine().getStatusCode(), EntityUtils.toString(
response.getEntity(), DEFAULT_CHARSET));
}
public HttpResponse doPost(String url) throws Exception {
return this.doPost(url, null);
}
/**
* 封住请求的响应码和响应的内容
*/
public class HttpResponse {
/** http status */
private Integer code;
/** http response content */
private String body;
public HttpResponse() { }
public HttpResponse(Integer code, String body) {
this.code = code;
this.body = body;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
}
- User
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@RequiredArgsConstructor
public class User {
private Long id;
private String username;
}
- controller
@RestController
public class TestController {
@Autowired
private HttpClient httpClient;
@GetMapping("testGet")
public String testGet() throws Exception {
return httpClient.doGet("http://www.baidu.com");
}
@PostMapping("tesPost")
public User tesPost() throws Exception {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("id", "1");
paramMap.put("username", "mengda");
User user = httpClient.doPost("http://localhost:8080/doPost", paramMap, User.class);
return user;
}
@PostMapping("doPost")
public User doPost(@RequestBody User user) {
User newUser = new User(user.getId(), user.getUsername() + "y");
return newUser;
}
}