1.HttpClient介绍
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.5
总结:HttpClient就是基于java实现http请求的工具包,可以通过httpClient请求对返回值数据进行二次操作.
2.httpclient的jar包
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
3.httpclient get请求
public void test01() throws ClientProtocolException, IOException{
//1.创建HTTPclient对象
CloseableHttpClient client = HttpClients.createDefault();
//2.定义请求路径
String url = “https://xxx”
//3.定义请求的类型
HttpGet httpGet = new HttpGet(uri);
//4.获取请求结果
CloseableHttpResponse httpResponse = client.execute(httpGet);
//5.获取响应结果
String result = EntityUtils.toString(httpResponse.getEntity());
}
2.httpclient post请求
public void testPost() throws ClientProtocolException, IOException{
//1.创建HTTPclient对象
CloseableHttpClient client = HttpClients.createDefault();
//2.定义请求路径
String uri = "https://xxx";
//3.定义请求类型
HttpPost httpPost = new HttpPost(uri);
//4.获取请求结果
CloseableHttpResponse response = client.execute(httpPost);
//5.判断请求是否正确返回
if (response.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(response.getEntity());
}
}
spring整合httpclient
1.代码层级结构
2.properties文件
#从连接池中获取到连接的最长时间
http.request.connectionRequestTimeout=500
#数据连接的最长时间
http.request.connectTimeout=5000
#数据传输的最长时间
http.request.socketTimeout=30000
#提交请求前测试连接是否可用
http.request.staleConnectionCheckEnabled=true
#设置连接总数
http.pool.maxTotal=200
#设置每个地址的并发数
http.pool.defaultMaxPerRoute=100
3.spring配置文件
<!-- 定义httpclient连接池 -->
<bean id="httpClientConnectionManager" class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager" destroy-method="close">
<!-- 设置连接总数 -->
<property name="maxTotal" value="${http.pool.maxTotal}"></property>
<!-- 设置每个地址的并发数 -->
<property name="defaultMaxPerRoute" value="${http.pool.defaultMaxPerRoute}"></property>
</bean>
<!-- 定义 HttpClient工厂,这里使用HttpClientBuilder构建-->
<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create">
<property name="connectionManager" ref="httpClientConnectionManager"></property>
</bean>
<!-- 得到httpClient的实例 -->
<bean id="httpClient" factory-bean="httpClientBuilder" factory-method="build"/>
<!-- 定期清理无效的连接 -->
<bean class="com.jt.common.util.IdleConnectionEvictor" destroy-method="shutdown">
<constructor-arg index="0" ref="httpClientConnectionManager" />
<!-- 间隔一分钟清理一次 -->
<constructor-arg index="1" value="60000" />
</bean>
<!-- 定义requestConfig的工厂 -->
<bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig.Builder">
<!-- 从连接池中获取到连接的最长时间 -->
<property name="connectionRequestTimeout" value="${http.request.connectionRequestTimeout}"/>
<!-- 创建连接的最长时间 -->
<property name="connectTimeout" value="${http.request.connectTimeout}"/>
<!-- 数据传输的最长时间 -->
<property name="socketTimeout" value="${http.request.socketTimeout}"/>
<!-- 提交请求前测试连接是否可用 -->
<property name="staleConnectionCheckEnabled" value="${http.request.staleConnectionCheckEnabled}"/>
</bean>
<!-- 得到requestConfig实例 -->
<bean id="requestConfig" factory-bean="requestConfigBuilder" factory-method="build" />
3.httpclient工具类
@Service
public class HttpClientService {
@Autowired(required=false)
private CloseableHttpClient httpClient;
@Autowired(required=false)
private RequestConfig requestConfig;
/**编辑HttpGet请求
* get:localhost:8091/add?id=1&name=tom
* 1.使用map<k,v>集合信息,保存传递的参数
* 2.指定uri
* 3.设定字符集编码
*/
public String doGet(String uri,Map<String,String> params,String charset){
String result = null;
//设定字符集
if(StringUtils.isEmpty(charset)){
charset = "UTF-8";
}
try {
//判断是否还有参数
if(params != null){
//使用URIBuilder进行请求了路径的拼接
URIBuilder builder = new URIBuilder(uri);
for (Map.Entry<String,String> entry : params.entrySet()) {
builder.addParameter(entry.getKey(), entry.getValue());
// add?id=1&name=tom 生成新的请求路径
uri = builder.build().toString();
}
}
//定义请求对象
HttpGet httpGet = new HttpGet(uri);
//定义请求的链接时长
httpGet.setConfig(requestConfig);
CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
//判断请求是否正确
if(httpResponse.getStatusLine().getStatusCode() == 200){
result = EntityUtils.toString(httpResponse.getEntity(),charset);
}
}catch (Exception e) {
e.printStackTrace();
}
return result;
}
public String doGet(String uri,Map<String,String> params){
return doGet(uri, params, null);
}
public String doGet(String uri){
return doGet(uri, null);
}
}
4.业务逻辑
前台controller
@Controller
@RequestMapping("/items")
public class ItemController {
@Autowired
private ItemService itemService;
//http://www.jt.com/items/562379.html
@RequestMapping("/{itemId}")
public String findItemById(@PathVariable Long itemId,Model model){
Item item = itemService.findItemById(itemId);
ItemDesc itemDesc = itemService.findItemDescById(itemId);
model.addAttribute("item",item);
model.addAttribute("itemDesc",itemDesc);
return "item";
}
}
前台service
@Service
public class ItemServiceImpl implements ItemService {
@Autowired
private HttpClientService httpClient;
private static ObjectMapper objectMapper = new ObjectMapper();
@Override
public Item findItemById(Long itemId) {
//1.定义远程访问的uri
String uri = "http://manage.jt.com/web/item/findItemById/"+itemId;
//2.发起请求获取远程服务端数据
String jsonData = httpClient.doGet(uri);
Item item = null;
try {
item = objectMapper.readValue(jsonData, Item.class);
} catch (Exception e) {
e.printStackTrace();
}
return item;
}
@Override
public ItemDesc findItemDescById(Long itemId) {
//1.定义远程访问的uri
String uri = "http://manage.jt.com/web/item/findItemDescById/"+itemId;
//2.发起请求获取远程服务端数据
String jsonData = httpClient.doGet(uri);
ItemDesc itemDesc = null;
try {
itemDesc = objectMapper.readValue(jsonData, ItemDesc.class);
} catch (Exception e) {
e.printStackTrace();
}
return itemDesc;
}
}
后台controller
@Controller
@RequestMapping("/web/item")
public class WebItemController {
@Autowired
private ItemService itemService;
//前台获取Item对象和ItemDesc对象
@RequestMapping("/findItemById/{itemId}")
@ResponseBody
public Item findItemById(@PathVariable Long itemId){
return itemService.findItemById(itemId);
}
//ItemDesc对象
@RequestMapping("/findItemDescById/{itemId}")
@ResponseBody
public ItemDesc findItemDescById(@PathVariable Long itemId){
return itemService.findItemDescById(itemId);
}
}
后台service
@Override
public ItemDesc findItemDescById(Long itemId) {
return itemDescMapper.selectByPrimaryKey(itemId);
}
@Override
public Item findItemById(Long itemId) {
return itemMapper.selectByPrimaryKey(itemId);
}