iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java服务调用RestTemplate与HttpClient的使用详解
  • 116
分享到

Java服务调用RestTemplate与HttpClient的使用详解

2024-04-02 19:04:59 116人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录概述RestTemplate概述及依赖配置类使用GET请求POST请求上传文件HttpClient概述使用概述 常见的远程调用方式有以下2种: rpc: Remote Produ

概述

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

  • rpc: Remote Produce Call远程过程调用,类似的还有RMI(remote method invoke)。自定义数据格式,基于原生tcp通信,速度快,效率高。早期的WEBservice,现在热门的dubbo,都是RPC的典型代表。
  • Http: http其实是一种网络传输协议,基于TCP,规定了数据传输的格式。 现在客户端浏览器与服务端通信基本都是采用Http协议,也可以用来进行远程服务调用。缺点是消息封装臃肿,优势是对服务的提供和调用方没有任何技术限定,自由灵活,更符合微服务理念。现在热门的Rest风格,就可以通过http协议来实现。

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

如果项目的技术栈多样化,主要采用了springSpringBoot框架,那么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
public class RestTemplateConfig {
   @Bean
   public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
       return new RestTemplate(factory);
   }
   @Bean
   public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
       SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
       factory.setReadTimeout(150 * 1000); // ms
       factory.setConnectTimeout(150 * 1000); // ms
       return factory;
   }
}

进阶配置

import org.apache.http.client.HttpClient;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
    
    @Bean
    public HttpClientConnectionManager poolingHttpClientConnectionManager() {
        
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        // 最大连接数
        poolingHttpClientConnectionManager.setMaxTotal(500);
        // 同路由并发数(每个主机的并发)
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
        return poolingHttpClientConnectionManager;
    }
    
    @Bean
    public HttpClient httpClient(HttpClientConnectionManager poolingHttpClientConnectionManager) {
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // 设置http连接管理器
        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
        
        // 设置默认请求头
        
        return httpClientBuilder.build();
    }
    
    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) {
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        // httpClient创建器
        clientHttpRequestFactory.setHttpClient(httpClient);
        // 连接超时时间/毫秒(连接上服务器(握手成功)的时间,超出抛出connect timeout)
        clientHttpRequestFactory.setConnectTimeout(5 * 1000);
        // 数据读取超时时间(SocketTimeout)/毫秒(服务器返回数据(response)的时间,超过抛出read timeout)
        clientHttpRequestFactory.setReadTimeout(10 * 1000);
        // 从连接池获取请求连接的超时时间,不宜过长,必须设置/毫秒(超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool)
        clientHttpRequestFactory.setConnectionRequestTimeout(10 * 1000);
        return clientHttpRequestFactory;
    }
    
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory clientHttpRequestFactory) {
        // 配置请求工厂
        return new RestTemplate(clientHttpRequestFactory);
    }
}

使用

实体类

@Data
@Builder
@NoArgsConstrutor
@AllArgsConstrutor
public class BaseResponse<TempUser> implements Serializable {
    private static final long serialVersionUID  = 1L;
    private String responseCode;
    private String responseMessage;
    private List<TempUser> responseData;
}
@Data
@Builder
@NoArgsConstrutor
@AllArgsConstrutor
public class TempUser implements Serializable {
    private static final long serialVersionUID  = 1L;
    private String userName;   
    private Integer age;
}

GET请求

普通访问

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

返回HTTP状态

ResponseEntity<BaseResponse> responseEntity = restTemplate.getForEntity(
    "http://localhost:8080/cs-admin/rest/getUser?userName=张三&age=18", TempUser.class);
// 获取状态对象
httpstatus httpStatus = responseEntity.getStatusCode();
// 获取状态码
int statusCodeValue = responseEntity.getStatusCodeValue();
// 获取headers
HttpHeaders httpHeaders = responseEntity.getHeaders();
// 获取body
BaseResponse result = responseEntity.getBody();

映射请求参数

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("userName", "张三");
paramMap.put("age", 18);
BaseResponse result = restTemplate.getForObject(
    "http://localhost:8080/cs-admin/rest/getUser?userName={userName}&age={age}", 
    BaseResponse.class, paramMap);

POST请求

普通访问接口

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

带HEAD访问接口

// 请求头信息
HttpHeaders headers = new HttpHeaders();
//headers.setContentType(MediaType.valueOf("application/JSON;charset=UTF-8"));
headers.setContentType(MediaType.APPLICATION_jsON_UTF8);
//headers.add("headParam1", "headParamValue");
// 请求体内容
TempUser param = new TempUser();
param.setUserName("张三");
param.setAge(18);
// 组装请求信息
HttpEntity<TempUser> httpEntity=new HttpEntity<>(param, headers);
BaseResponse result = restTemplate.postForObject("http://localhost:8080/cs-admin/rest/getPostUser", 
                                             httpEntity, BaseResponse.class);

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

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("userName", "张三");
paramMap.put("age", 18);
BaseResponse result = restTemplate.postForObject(
    "http://localhost:8080/cs-admin/rest/getPostUserNoBody?userName={userName}&age={age}", 
    null, BaseResponse.class, paramMap);
System.out.println(result);

上传文件

后台接口代码:

@RequestMapping("uploadFile")
public TempUser uploadFile(HttpServletRequest request, TempUser fORM) {
    MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
    //获取文件信息
    MultipartFile multipartFile = multipartHttpServletRequest.getFile("file");
    TempUser tempUser = new TempUser();
    if (multipartFile != null) {
        tempUser.setUserName(form.getUserName() + " " + multipartFile.getOriginalFilename());
    }
    if(form!=null){
        tempUser.setAge(form.getAge());
    }
    return tempUser;
}

访问方式:

// 文件
FileSystemResource file=new FileSystemResource("D:\\elasticsearch权威指南(中文版).pdf");
// 设置请求内容
MultiValueMap<String, Object> param=new LinkedMultiValueMap<>();
param.add("file", file);
// 其他参数
param.add("userName", "张三");
param.add("age", 18);
// 组装请求信息
HttpEntity<MultiValueMap<String, Object>> httpEntity=new HttpEntity<>(param);
// 发送请求
TempUser result = 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工具类

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import java.net.URI;
import java.NIO.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
public class HttpClientUtil {
    public static final String APPLICATION_JSON_VALUE = "application/json";
    private static final Logger logger = log;
    private static final Integer CONN_TIME_OUT = 3000;// 超时时间豪秒
    private static final Integer SOCKET_TIME_OUT = 10000;
    
    private static final Integer DEFAULT_MAX_PER_ROUTE = 40;
    
    private static final Integer MAX_TOTAL = 400;
    private static HttpClient httpClient;
    static {
        // 请求配置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(CONN_TIME_OUT)
                .setConnectionRequestTimeout(CONN_TIME_OUT)
                .setSocketTimeout(SOCKET_TIME_OUT)
                .build();
        // 管理 http连接池
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);
        cm.setMaxTotal(MAX_TOTAL);
        httpClient = HttpClients.custom()
            .setConnectionManager(cm)
            .setDefaultRequestConfig(requestConfig)
            .build();
    }
    
    public static String requestGet(String url, Map<String, String> paramsMap) throws Exception {
        logger.info("GET request  url:{} params:{}", url, paramsMap);
        Long start = System.currentTimeMillis();
        List<NameValuePair> params = initParams(paramsMap);
        // Get请求
        HttpGet httpGet = new HttpGet(url);
        try {
            // 设置参数
            String str = EntityUtils.toString(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
            String uriStr = StringUtils.isEmpty(str) ? 
                httpGet.getURI().toString() : httpGet.getURI().toString() + "?" + str;
            httpGet.setURI(new URI(uriStr));
            // 发送请求
            HttpResponse response = httpClient.execute(httpGet);
            logger.info("GET request  url:{} response:{} time:{}",
                    url, response, System.currentTimeMillis() - start);
            // 获取返回数据
            return getSuccessRetFromResp(response, url, JSON.toJSONString(paramsMap));
        } finally {
            // 必须释放连接,不然连接用完后会阻塞
            httpGet.releaseConnection();
        }
    }
    
    public static String requestPost(String url, Map<String, String> paramsMap) throws Exception {
        logger.info("POST request  url:{} params:{}", url, paramsMap);
        Long start = System.currentTimeMillis();
        List<NameValuePair> params = initParams(paramsMap);
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
            HttpResponse response = httpClient.execute(httpPost);
            logger.info("POST request  url:{} response:{}  time:{}",
                    url, response, System.currentTimeMillis() - start);
            String retStr = getSuccessRetFromResp(response, url, JSON.toJSONString(paramsMap));
            return retStr;
        } finally {
            httpPost.releaseConnection();
        }
    }
    
    public static String requestPostJsonStr(String url, String json) throws Exception {
        logger.info("POST request  url:{} params:{}", url, json);
        long start = System.currentTimeMillis();
        HttpPost httpPost = new HttpPost(url);
        try {
            StringEntity entity = new StringEntity(json, Consts.UTF_8);
            entity.setContentType(APPLICATION_JSON_VALUE);
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            logger.info("POST request  url:{} response:{}  time:{}", 
                        url, response, System.currentTimeMillis() - start);
            return getSuccessRetFromResp(response, url, json);
        } finally {
            // 资源释放
            httpPost.releaseConnection();
        }
    }
    
    public static String requestPostJson(String url, Object obj) throws Exception {
        String params = JSON.toJSONString(obj);
        return requestPostJsonStr(url, params);
    }
    private static String getSuccessRetFromResp(HttpResponse response, String url, String params) throws Exception {
        String retStr = "";
        // 检验状态码,如果成功接收数据
        int code = response.getStatusLine().getStatusCode();
        if (code == 200) {
            retStr = EntityUtils.toString(response.getEntity(), Consts.UTF_8);
        } else {
            throw new RuntimeException(String.format("Http request error:%s, url:%s, params:%s", response, url, params));
        }
        logger.info("Http request retStr:{}. url:{}", retStr, url);
        return retStr;
    }
    private static List<NameValuePair> initParams(Map<String, String> paramsMap) {
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        if (paramsMap == null)
            return params;
        for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
            params.add(new BasicNameValuePair(entry.geTKEy(), entry.getValue()));
        }
        return params;
    }
}

到此这篇关于Java服务调用RestTemplate与HttpClient的使用详解的文章就介绍到这了,更多相关Java RestTemplate与HttpClient内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java服务调用RestTemplate与HttpClient的使用详解

本文链接: https://www.lsjlt.com/news/152098.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java服务调用RestTemplate与HttpClient的使用详解
    目录概述RestTemplate概述及依赖配置类使用GET请求POST请求上传文件HttpClient概述使用概述 常见的远程调用方式有以下2种: RPC: Remote Produ...
    99+
    2024-04-02
  • Java服务RestTemplate与HttpClient如何使用
    这篇“Java服务RestTemplate与HttpClient如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Jav...
    99+
    2023-07-02
  • Java服务RestTemplate与HttpClient怎么使用
    本篇内容主要讲解“Java服务RestTemplate与HttpClient怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java服务RestTemplate与HttpClient怎么使...
    99+
    2023-07-06
  • Java原生HttpClient的使用详解
    目录1.信任证书管理类2.HttpClient类3.发送请求工具类4.测试提到Java发送HTTP请求,大家首先想到的是用apache的HttpClient,或者squareup的O...
    99+
    2024-04-02
  • HttpClient jar包使用详解
    HttpClient是一个开源的HTTP客户端工具包,用来进行HTTP通信。它可以用来发送HTTP请求和接收HTTP响应,支持HTT...
    99+
    2023-09-15
    HttpClient
  • java怎么使用HttpClient调用接口
    这篇文章主要介绍“java怎么使用HttpClient调用接口”,在日常操作中,相信很多人在java怎么使用HttpClient调用接口问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java怎么使用HttpC...
    99+
    2023-07-04
  • java中如何使用HttpClient调用接口
    目录java使用HttpClient调用接口HttpClient 提供的主要的功能直接言归正传了!!!!上代码java的HttpClient调用远程接口使用方法实例java使用Htt...
    99+
    2022-11-13
    java使用HttpClient HttpClient调用接口 java HttpClient
  • Java使用HttpClient详细示例
    目录准备环节第一步:在pom.xml中引入HttpClient的依赖第二步:引入fastjson依赖详细使用示例GET无参:GET有参(方式一:直接拼接URL):GET有参(方式二:...
    99+
    2024-04-02
  • 使用HttpClient调用接口的实例讲解
    一,编写返回对象public class HttpResult {// 响应的状态码private int code;// 响应的响应体private String body;get/set…}...
    99+
    2023-05-31
    httpclient 调用 接口
  • 基于RestTemplate的使用方法(详解)
    1.postForObject :传入一个业务对象,返回是一个String调用方:BaseUser baseUser=new BaseUser();baseUser.setUserid(userid);baseUser.setPass(pa...
    99+
    2023-05-31
    resttemplate emp
  • RestTemplate调用POST和GET请求示例详解
    目录正文一、POST请求调用二、GET请求调用三、Exchange调用正文 在日常开发过程中,http接口不仅提供给前端调用,有的时候还需要提供给其他业务方调用,在后台调用http...
    99+
    2023-05-13
    RestTemplate调用POST GET RestTemplate调用
  • SpringCloud服务的发现与调用详解
    目录前言一、服务提供者二、服务消费者总结相关推荐 上一章:Eureka注册中心 前言 上一章中,我们介绍了Eureka注册中心及集群的搭建,这一节将介绍服务的发现和调用。注意,这个...
    99+
    2024-04-02
  • Java 方法的定义与调用详解
    目录1.方法概述2.方法的定义和调用2.1 方法定义2.2 方法调用2.3 方法的调用过程2.4 方法练习3.带参数方法的定义和调用3.1带参数方法定义3.2带参数方法调用1.方法概...
    99+
    2024-04-02
  • springcloud中Ribbon和RestTemplate实现服务调用与负载均衡
    文件目录结构 文件目录结构很重要,特别注意的是rule文件要放在主启动类上一级位置,才能够扫描。 写pom <dependencies> <!...
    99+
    2024-04-02
  • Java使用Hutool调用WebService接口详解
    提示:本文显示baidu.com,皆为脱敏用,并非真正地址。 目录 前言 一、WebService是什么? 二、使用步骤 1.验证链接。 2.Soap调用测试 3.获取需要用到的数据 4.Hutool工具类调用 三、示例 1.单个入...
    99+
    2023-09-01
    1024程序员节
  • JAVA中的HTTPS接口怎么利用HttpClient进行调用
    JAVA中的HTTPS接口怎么利用HttpClient进行调用?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。为了避免需要证书,所以用一个类继承DefaultHttpClient...
    99+
    2023-05-31
    java httpclient https
  • Java FileInputStream与FileOutputStream使用详解
    什么是InputStream和OutputStream? InputStream和OutputStream是抽象类,是所有字节输入流和输出流的父类。这里,我们首先要分清楚两个概念:...
    99+
    2024-04-02
  • 使用Spring RestTemplate 详解实践使用及拓展增强
    目录RestTemplate 是什么?主要类和接口基础使用Get获取对象或对象集合Post 发送对象或集合上传文件上传多个文件Spring RestTemplate 拓展继承Rest...
    99+
    2024-04-02
  • 关于远程调用RestTemplate的使用避坑指南
    目录一、前言介绍二、 问题记录1. 慎!【url参数中有json字符串】2. 慎!【url参数中有经过URLEncode的字符串】3. 慎!【url参数中存在特殊字符】 --- 针对...
    99+
    2024-04-02
  • Java Http请求方式之RestTemplate常用方法详解
    目录引言常见用法简单Get\Post请求Post提交常规表单Post上传文件配置项请求添加Cookie\Header配置请求工厂 超时、代理配置拦截器、转换器,错误处理错误重试(额外...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作