一周的忙碌过后又到了愉快的周末,又开始了作为小白的成长之旅。
作为一个资深的中转部门,什么最重要呢,当然是curl了,调用其他地方的接口,获取数据,然后进行处理。
所以今天的目标就是实现curl了!
在pom.xml将加入下面内容
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</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>
复制代码
配置properties文件
#最大连接数 http.maxTotal = 100 #并发数 http.defaultMaxPerRoute = 20 #创建连接的最长时间 http.connectTimeout=1000 #从连接池中获取到连接的最长时间 http.connectionRequestTimeout=500 #数据传输的最长时间 http.socketTimeout=10000 http.validateAfterInactivity=1000 复制代码
新增HttpClientConfiguration.java
package com.example.demo.controller;
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.java
package com.example.demo.controller;
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;
}
}
}
复制代码
CurlController.java 里面实现两个接口,一个是get方式的,一个是post方式的。
package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class CurlController {
@Autowired
private HttpClient httpClient;
@RequestMapping("/curlBaidu")
public String curlBaidu() throws Exception {
return httpClient.doGet("http://www.baidu.com");
}
@RequestMapping("/curlLocation")
public String curlLocation() throws Exception {
Map<String, Object> name = new HashMap<>();
name.put("name", "caohaoyu");
name.put("name2", "chy");
HttpClient.HttpResponse httpResult = httpClient.doPost("http://localhost:8080/helloByParam", name);
String body = httpResult.getBody();
JSONObject jsonObject = JSONObject.parseObject(body);
return jsonObject.getString("data");
}
}
复制代码
在原有的HelloController.java修改helloByParam接口,接收post传输过来的数据并直接返回。
@RequestMapping("/helloByParam")
public String helloByParam(@RequestBody JSONObject jsonObject) {
JSONObject result = new JSONObject();
result.put("msg", "ok");
result.put("code", "0");
result.put("data", jsonObject);
return result.toJSONString();
}
复制代码
get实现结果:
post实现结果:
圆满完成简单版curl的实现!
java是强类型的,这点对于写惯了php这种弱类型的人来说一开始确实还是有点别扭的。不过编辑器还是挺好用的,以后慢慢适应吧。
还有就是java对调用方式也比较严格,需要注意。不能像php简单的 $_REQUEST 来同时支持post和get。