首页后端开发PHPJava服务RestTemplate与HttpClient怎么使用

Java服务RestTemplate与HttpClient怎么使用

时间2023-07-10 20:58:02发布访客分类PHP浏览1261
导读:本篇内容主要讲解“Java服务RestTemplate与HttpClient怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java服务RestTemplate与HttpClient怎么使...
本篇内容主要讲解“Java服务RestTemplate与HttpClient怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java服务RestTemplate与HttpClient怎么使用”吧!

概述

常见的远程调用方式有以下2种:

  • RPC: Remote Produce Call远程过程调用,类似的还有RMI(remote method invoke)。自定义数据格式,基于原生TCP通信,速度快,效率高。早期的webservice,现在热门的dubbo,都是RPC的典型代表。

  • Http: http其实是一种网络传输协议,基于TCP,规定了数据传输的格式。 现在客户端浏览器与服务端通信基本都是采用Http协议,也可以用来进行远程服务调用。缺点是消息封装臃肿,优势是对服务的提供和调用方没有任何技术限定,自由灵活,更符合微服务理念。现在热门的Rest风格,就可以通过http协议来实现。

如果项目全部采用 Java技术栈,那么使用Dubbo作为微服务架构是一个不错的选择。

如果项目的技术栈多样化,主要采用了Spring和SpringBoot框架,那么SpringCloud搭建微服务是不二之选,使用Http方式来实现服务间调用。

java开发中,使用http连接,访问第三方网络接口,通常使用的连接工具为RestTemplate、HttpClient和OKHttp。

RestTemplate

概述及依赖

HttpClient和OKHttp两种连接工具,使用起来比较复杂,如果使用spring框架,可以使用restTemplate来进行http连接请求。

restTemplate默认的连接方式是java中的HttpConnection,可以使用ClientHttpRequestFactory指定不同的HTTP连接方式。

依赖

dependency>
    
groupId>
    org.springframework/groupId>
    
artifactId>
    spring-web/artifactId>
    
version>
    5.2.2.RELEASE/version>
    
/dependency>
    
dependency>
    
groupId>
    org.apache.httpcomponents/groupId>
    
artifactId>
    httpclient/artifactId>
    
version>
    4.5.7/version>
    
/dependency>
    
配置类

基础配置

@Configuration
publicclassRestTemplateConfig{

@Bean
publicRestTemplaterestTemplate(ClientHttpRequestFactoryfactory){
    
returnnewRestTemplate(factory);

}

@Bean
publicClientHttpRequestFactorysimpleClientHttpRequestFactory(){
    
SimpleClientHttpRequestFactoryfactory=newSimpleClientHttpRequestFactory();
    
factory.setReadTimeout(150*1000);
    //ms
factory.setConnectTimeout(150*1000);
    //ms
returnfactory;

}

}
    

进阶配置

importorg.apache.http.client.HttpClient;
    
importorg.apache.http.conn.HttpClientConnectionManager;
    
importorg.apache.http.impl.client.HttpClientBuilder;
    
importorg.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    
importorg.springframework.context.annotation.Bean;
    
importorg.springframework.context.annotation.Configuration;
    
importorg.springframework.http.client.ClientHttpRequestFactory;
    
importorg.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    
importorg.springframework.web.client.RestTemplate;

@Configuration
publicclassRestTemplateConfig{

/**
*http连接管理器
*/
@Bean
publicHttpClientConnectionManagerpoolingHttpClientConnectionManager(){
    
/*//注册http和https请求
RegistryConnectionSocketFactory>
    registry=RegistryBuilder.ConnectionSocketFactory>
    create()
.register("http",PlainConnectionSocketFactory.getSocketFactory())
.register("https",SSLConnectionSocketFactory.getSocketFactory())
.build();
    
PoolingHttpClientConnectionManagerpoolingHttpClientConnectionManager=newPoolingHttpClientConnectionManager(registry);
    */
PoolingHttpClientConnectionManagerpoolingHttpClientConnectionManager=newPoolingHttpClientConnectionManager();
    
//最大连接数
poolingHttpClientConnectionManager.setMaxTotal(500);
    
//同路由并发数(每个主机的并发)
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
    
returnpoolingHttpClientConnectionManager;

}

/**
*HttpClient
*@parampoolingHttpClientConnectionManager
*/
@Bean
publicHttpClienthttpClient(HttpClientConnectionManagerpoolingHttpClientConnectionManager){
    
HttpClientBuilderhttpClientBuilder=HttpClientBuilder.create();
    
//设置http连接管理器
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
    
/*//设置重试次数,默认是3次,没有开启
httpClientBuilder.setRetryHandler(newDefaultHttpRequestRetryHandler(3,true));
    */
//设置默认请求头
/*ListHeader>
    headers=newArrayList>
    ();
    
headers.add(newBasicHeader("User-Agent","Mozilla/5.0(WindowsNT6.1)AppleWebKit/537.36(KHTML,likeGecko)Chrome/31.0.1650.16Safari/537.36"));
    
headers.add(newBasicHeader("Accept-Encoding","gzip,deflate"));
    
headers.add(newBasicHeader("Accept-Language","zh-CN"));
    
headers.add(newBasicHeader("Connection","Keep-Alive"));
    
headers.add(newBasicHeader("Content-type","application/json;
    charset=UTF-8"));
    
httpClientBuilder.setDefaultHeaders(headers);
    */
returnhttpClientBuilder.build();

}

/**
*请求连接池配置
*@paramhttpClient
*/
@Bean
publicClientHttpRequestFactoryclientHttpRequestFactory(HttpClienthttpClient){
    
HttpComponentsClientHttpRequestFactoryclientHttpRequestFactory=newHttpComponentsClientHttpRequestFactory();
    
//httpClient创建器
clientHttpRequestFactory.setHttpClient(httpClient);
    
//连接超时时间/毫秒(连接上服务器(握手成功)的时间,超出抛出connecttimeout)
clientHttpRequestFactory.setConnectTimeout(5*1000);
    
//数据读取超时时间(socketTimeout)/毫秒(服务器返回数据(response)的时间,超过抛出readtimeout)
clientHttpRequestFactory.setReadTimeout(10*1000);
    
//从连接池获取请求连接的超时时间,不宜过长,必须设置/毫秒(超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException:Timeoutwaitingforconnectionfrompool)
clientHttpRequestFactory.setConnectionRequestTimeout(10*1000);
    
returnclientHttpRequestFactory;

}

/**
*rest模板
*/
@Bean
publicRestTemplaterestTemplate(ClientHttpRequestFactoryclientHttpRequestFactory){
    
//配置请求工厂
returnnewRestTemplate(clientHttpRequestFactory);

}

}
    
使用

实体类

@Data
@Builder
@NoArgsConstrutor
@AllArgsConstrutor
publicclassBaseResponseTempUser>
implementsSerializable{
    
privatestaticfinallongserialVersionUID=1L;
    
privateStringresponseCode;
    
privateStringresponseMessage;
    
privateListTempUser>
    responseData;

}
    
@Data
@Builder
@NoArgsConstrutor
@AllArgsConstrutor
publicclassTempUserimplementsSerializable{
    
privatestaticfinallongserialVersionUID=1L;
    
privateStringuserName;
    
privateIntegerage;

}
    
GET请求

普通访问

BaseResponseresult=restTemplate.getForObject(
"http://localhost:8080/cs-admin/rest/getUser?userName=张三&
    age=18",BaseResponse.class);
    

返回HTTP状态

ResponseEntityBaseResponse>
    responseEntity=restTemplate.getForEntity(
"http://localhost:8080/cs-admin/rest/getUser?userName=张三&
    age=18",TempUser.class);
    
//获取状态对象
HttpStatushttpStatus=responseEntity.getStatusCode();
    
//获取状态码
intstatusCodeValue=responseEntity.getStatusCodeValue();
    
//获取headers
HttpHeadershttpHeaders=responseEntity.getHeaders();
    
//获取body
BaseResponseresult=responseEntity.getBody();
    

映射请求参数

MapString,Object>
    paramMap=newHashMap>
    ();
    
paramMap.put("userName","张三");
    
paramMap.put("age",18);

BaseResponseresult=restTemplate.getForObject(
"http://localhost:8080/cs-admin/rest/getUser?userName={
userName}
    &
age={
age}
    ",
BaseResponse.class,paramMap);
    
POST请求

普通访问接口

TempUserparam=newTempUser();
    
param.setUserName("张三");
    
param.setAge(18);
    
BaseResponseresult=restTemplate.postForObject("http://localhost:8080/cs-admin/rest/getPostUser",
param,BaseResponse.class);
    

带HEAD访问接口

//请求头信息
HttpHeadersheaders=newHttpHeaders();
    
//headers.setContentType(MediaType.valueOf("application/json;
    charset=UTF-8"));
    
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
    
//headers.add("headParam1","headParamValue");
    
//请求体内容
TempUserparam=newTempUser();
    
param.setUserName("张三");
    
param.setAge(18);
    
//组装请求信息
HttpEntityTempUser>
    httpEntity=newHttpEntity>
    (param,headers);
    
BaseResponseresult=restTemplate.postForObject("http://localhost:8080/cs-admin/rest/getPostUser",
httpEntity,BaseResponse.class);
    

无请求体的访问:仅method为post,传参方式仍然为get的param方式

MapString,Object>
    paramMap=newHashMap>
    ();
    
paramMap.put("userName","张三");
    
paramMap.put("age",18);

BaseResponseresult=restTemplate.postForObject(
"http://localhost:8080/cs-admin/rest/getPostUserNoBody?userName={
userName}
    &
age={
age}
    ",
null,BaseResponse.class,paramMap);
    
System.out.println(result);
    
上传文件

后台接口代码:

@RequestMapping("uploadFile")
publicTempUseruploadFile(HttpServletRequestrequest,TempUserform){
    
MultipartHttpServletRequestmultipartHttpServletRequest=(MultipartHttpServletRequest)request;
    
//获取文件信息
MultipartFilemultipartFile=multipartHttpServletRequest.getFile("file");
    
TempUsertempUser=newTempUser();

if(multipartFile!=null){
    
tempUser.setUserName(form.getUserName()+""+multipartFile.getOriginalFilename());

}

if(form!=null){
    
tempUser.setAge(form.getAge());

}
    
returntempUser;

}
    

访问方式:

//文件
FileSystemResourcefile=newFileSystemResource("D:\\Elasticsearch权威指南(中文版).pdf");
    
//设置请求内容
MultiValueMapString,Object>
    param=newLinkedMultiValueMap>
    ();
    
param.add("file",file);
    
//其他参数
param.add("userName","张三");
    
param.add("age",18);
    
//组装请求信息
HttpEntityMultiValueMapString,Object>
    >
    httpEntity=newHttpEntity>
    (param);
    
//发送请求
TempUserresult=restTemplate.postForObject("http://localhost:8080/cs-admin/rest/uploadFile",
httpEntity,TempUser.class);
    

HttpClient

概述

HttpClient 通过连接池创建连接:

  • 管理连接的基本单位是Route(路由),每个路由上都会维护一定数量的HTTP连接

  • 每次调用后必须执行 releaseConnection

  • 路由可以理解为客户端机器到目标机器的一条线路

  • 如果不给 httpclient配置指定的连接管理器,httpclient会自动使用PoolingHttpClientConnectionManager作为连接管理器。

  • PoolingHttpClientConnectionManager默认的maxConnPerRoute和maxConnTotal分别是是2和20。也就是对于每个服务器最多只会维护2个连接,看起来有点少。所以,在日常使用时我们尽量使用自己配置的连接管理器比较好。

连接池:

  • 连接池技术作为创建和管理连接的缓冲池技术。

  • 连接池管理的对象是长连接

  • 有长连接的优势

**长连接:**是指客户端与服务器端一旦建立连接以后,可以进行多次数据传输而不需重新建立连接,

优势:

  • 省去了每次数据传输连接建立的时间开销

  • 资源的访问控制

**短连接:**每次数据传输都需要客户端和服务器端建立一次连接

使用

使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可:

  • 创建HttpClient对象

  • 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。

  • 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数,参数则必须用NameValuePair[]数组存储

  • 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse

  • 调用HttpResponse的getAllHeaders()getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponsegetEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容

  • 释放连接。无论执行方法是否成功,都必须释放连接

依赖:

dependency>
    
groupId>
    org.apache.httpcomponents/groupId>
    
artifactId>
    httpclient/artifactId>
    
version>
    4.5.2/version>
    
/dependency>
    
dependency>
    
groupId>
    org.apache.httpcomponents/groupId>
    
artifactId>
    httpclient-cache/artifactId>
    
version>
    4.5.2/version>
    
/dependency>
    
dependency>
    
groupId>
    org.apache.httpcomponents/groupId>
    
artifactId>
    httpmime/artifactId>
    
version>
    4.5.2/version>
    
/dependency>
    

java工具类

importcom.alibaba.fastjson.JSON;
    
importlombok.extern.slf4j.Slf4j;
    
importorg.apache.commons.lang3.StringUtils;
    
importorg.apache.http.Consts;
    
importorg.apache.http.HttpResponse;
    
importorg.apache.http.NameValuePair;
    
importorg.apache.http.client.HttpClient;
    
importorg.apache.http.client.config.RequestConfig;
    
importorg.apache.http.client.entity.UrlEncodedFormEntity;
    
importorg.apache.http.client.methods.HttpGet;
    
importorg.apache.http.client.methods.HttpPost;
    
importorg.apache.http.entity.StringEntity;
    
importorg.apache.http.impl.client.HttpClients;
    
importorg.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    
importorg.apache.http.message.BasicNameValuePair;
    
importorg.apache.http.util.EntityUtils;
    
importorg.slf4j.Logger;
    
importjava.net.URI;
    
importjava.nio.charset.StandardCharsets;
    
importjava.util.ArrayList;
    
importjava.util.List;
    
importjava.util.Map;

/**
*HttpClient工具类
*/
@Slf4j
publicclassHttpClientUtil{
    
publicstaticfinalStringAPPLICATION_JSON_VALUE="application/json";
    
privatestaticfinalLoggerlogger=log;
    
privatestaticfinalIntegerCONN_TIME_OUT=3000;
    //超时时间豪秒
privatestaticfinalIntegerSOCKET_TIME_OUT=10000;
    
/**每个路由的最大请求数,默认2*/
privatestaticfinalIntegerDEFAULT_MAX_PER_ROUTE=40;
    
/**最大连接数,默认20*/
privatestaticfinalIntegerMAX_TOTAL=400;
    
privatestaticHttpClienthttpClient;

static{
    
//请求配置
RequestConfigrequestConfig=RequestConfig.custom()
.setConnectTimeout(CONN_TIME_OUT)
.setConnectionRequestTimeout(CONN_TIME_OUT)
.setSocketTimeout(SOCKET_TIME_OUT)
.build();
    
//管理http连接池
PoolingHttpClientConnectionManagercm=newPoolingHttpClientConnectionManager();
    
cm.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);
    
cm.setMaxTotal(MAX_TOTAL);
    
httpClient=HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(requestConfig)
.build();

}
    
/**
*Get请求
*/
publicstaticStringrequestGet(Stringurl,MapString,String>
paramsMap)throwsException{

logger.info("GETrequesturl:{
}
params:{
}
    ",url,paramsMap);
    
Longstart=System.currentTimeMillis();
    
ListNameValuePair>
    params=initParams(paramsMap);
    
//Get请求
HttpGethttpGet=newHttpGet(url);

try{
    
//设置参数
Stringstr=EntityUtils.toString(newUrlEncodedFormEntity(params,StandardCharsets.UTF_8));
    
StringuriStr=StringUtils.isEmpty(str)?
httpGet.getURI().toString():httpGet.getURI().toString()+"?"+str;
    
httpGet.setURI(newURI(uriStr));
    
//发送请求
HttpResponseresponse=httpClient.execute(httpGet);

logger.info("GETrequesturl:{
}
response:{
}
time:{
}
    ",
url,response,System.currentTimeMillis()-start);
    
//获取返回数据
returngetSuccessRetFromResp(response,url,JSON.toJSONString(paramsMap));

}
finally{
    
//必须释放连接,不然连接用完后会阻塞
httpGet.releaseConnection();

}

}
    
/**
*Post请求,Map格式数据
*/
publicstaticStringrequestPost(Stringurl,MapString,String>
paramsMap)throwsException{

logger.info("POSTrequesturl:{
}
params:{
}
    ",url,paramsMap);
    
Longstart=System.currentTimeMillis();
    
ListNameValuePair>
    params=initParams(paramsMap);
    
HttpPosthttpPost=newHttpPost(url);

try{
    
httpPost.setEntity(newUrlEncodedFormEntity(params,Consts.UTF_8));
    
HttpResponseresponse=httpClient.execute(httpPost);

logger.info("POSTrequesturl:{
}
response:{
}
time:{
}
    ",
url,response,System.currentTimeMillis()-start);
    
StringretStr=getSuccessRetFromResp(response,url,JSON.toJSONString(paramsMap));
    
returnretStr;

}
finally{
    
httpPost.releaseConnection();

}

}

/**
*Post请求,json格式数据
*
*/
publicstaticStringrequestPostJsonStr(Stringurl,Stringjson)throwsException{

logger.info("POSTrequesturl:{
}
params:{
}
    ",url,json);
    
longstart=System.currentTimeMillis();
    
HttpPosthttpPost=newHttpPost(url);

try{
    
StringEntityentity=newStringEntity(json,Consts.UTF_8);
    
entity.setContentType(APPLICATION_JSON_VALUE);
    
httpPost.setEntity(entity);
    
HttpResponseresponse=httpClient.execute(httpPost);

logger.info("POSTrequesturl:{
}
response:{
}
time:{
}
    ",
url,response,System.currentTimeMillis()-start);
    
returngetSuccessRetFromResp(response,url,json);

}
finally{
    
//资源释放
httpPost.releaseConnection();

}

}

/**
*postObject格式数据
*/
publicstaticStringrequestPostJson(Stringurl,Objectobj)throwsException{
    
Stringparams=JSON.toJSONString(obj);
    
returnrequestPostJsonStr(url,params);

}

privatestaticStringgetSuccessRetFromResp(HttpResponseresponse,Stringurl,Stringparams)throwsException{
    
StringretStr="";
    
//检验状态码,如果成功接收数据
intcode=response.getStatusLine().getStatusCode();

if(code==200){
    
retStr=EntityUtils.toString(response.getEntity(),Consts.UTF_8);

}
else{
    
thrownewRuntimeException(String.format("Httprequesterror:%s,url:%s,params:%s",response,url,params));

}

logger.info("HttprequestretStr:{
}
.url:{
}
    ",retStr,url);
    
returnretStr;

}
    
privatestaticListNameValuePair>
    initParams(MapString,String>
paramsMap){
    
ListNameValuePair>
    params=newArrayListNameValuePair>
    ();
    
if(paramsMap==null)
returnparams;
    
for(Map.EntryString,String>
entry:paramsMap.entrySet()){
    
params.add(newBasicNameValuePair(entry.getKey(),entry.getValue()));

}
    
returnparams;

}

}
    

到此,相信大家对“Java服务RestTemplate与HttpClient怎么使用”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

javaresttemplatehttpclient

若转载请注明出处: Java服务RestTemplate与HttpClient怎么使用
本文地址: https://pptw.com/jishu/301628.html
javascript安装的步骤是什么 JavaScript循环问题怎么解决

游客 回复需填写必要信息