SpringBoot 整合 RestTemplate

本文详细介绍了在Spring Boot中如何整合和使用RestTemplate进行RESTful API调用,包括配置RestTemplateBean,创建工具类处理URL参数,以及各种方法如getForEntity、exchange和postForEntity的使用示例。同时提供了测试案例和实际接口调用的代码片段,展示了RestTemplate在远程服务调用中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、概述

1. 介绍

二、整合 RestTemplate

1. RestTemplateConfig 配置类

2. 工具类

3. RestTemplate 方法

4. getForEntity 方法

4.  exchange 方法

5.  postForEntity 方法

三、测试案例

1. RestTemplateController

2. 测试开始


如果发现本文有错误的地方,请大家毫不吝啬,多多指教,欢迎大家评论,谢谢! 

 


一、概述

当我们业务需求上,需要调用第三方外部接口数据,使用 RestTemplate 调用是一个不错的选择,调用起来比较灵活。

1. 介绍

Spring 框架提供的 RestTemplate 类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接,我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。

二、整合 RestTemplate

1. RestTemplateConfig 配置类

/**
 * RestTemplate配置
 * 这是一种JavaConfig的容器配置,用于spring容器的bean收集与注册,并通过参数传递的方式实现依赖注入。
 * "@Configuration"注解标注的配置类,都是spring容器配置类,springboot通过"@EnableAutoConfiguration"
 * 注解将所有标注了"@Configuration"注解的配置类,"一股脑儿"全部注入spring容器中。
 * 
 * @author Zou.LiPing
 *
 */
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(@Qualifier("simpleClientHttpRequestFactory") ClientHttpRequestFactory factory){
        return new RestTemplate(factory);
    }

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(15000);
        // 获取数据超时时间 毫秒
        factory.setReadTimeout(5000);
        return factory;
    }

}

2. 工具类


/**
 * 从配置文件获取URL
 * @date: 2021/4/29 14:48
 */
@Data
@Component
@ConfigurationProperties("remote.call")
public class RemoteCallProperties {

    private String productUrl;


}




@Slf4j
public class UrlUtils {

    /** 
     * url拼接参数
     * @param url
     * @param object
     * @date: 2020/6/19 11:51
     * @return: java.lang.String 
     */
    public static String getUrlAppendParm(String url, Object object) {
        StringBuffer stringBuffer = new StringBuffer(url);
        if (object instanceof Map) {
            Iterator iterator = ((Map) object).entrySet().iterator();
            if (iterator.hasNext()) {
                stringBuffer.append("?");
                Object element;
                while (iterator.hasNext()) {
                    element = iterator.next();
                    Map.Entry<String, Object> entry = (Map.Entry) element;
                    //过滤value为null,value为null时进行拼接字符串会变成 "null"字符串
                    if (entry.getValue() != null) {
                        stringBuffer.append(element).append("&");
                    }
                    url = stringBuffer.substring(0, stringBuffer.length() - 1);
                }
            }
        } else {
            throw new RuntimeException("url请求:" + url + "请求参数有误不是map类型");
        }
        log.info("url请求:" + url);
        return url;
    }
}



/**
 * 商品服务URL常量
 */
public interface ProductApiUrlConstants {

	/**
	 * 获取商品信息
	 */
	String GET_PRODUCT = "/product/getProduct";

    String INSERT_PRODUCT = "/product/insertProduct";
}


3. RestTemplate 方法

RestTemplate 定义了36个与 REST 资源交互的方法,其中的大多数都对应于HTTP的方法。
其实,这里面只有 11 个独立的方法,其中有十个有三种重载形式,而第十一个则重载了六次,这样一共形成了 36 个方法。

  • delete() 在特定的URL上对资源执行HTTP DELETE操作
  • exchange() 在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的
  • execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
  • getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
  • getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象
  • postForEntity() POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的
  • postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象
  • headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
  • optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息
  • postForLocation() POST 数据到一个URL,返回新创建资源的URL
  • put() PUT 资源到特定的URL

4. getForEntity 方法

@Override
    public ProductResp getByProductId(Long productId) {

        log.info("getProduct.req productId={}", productId);
        ProductResp productResp = new ProductResp();
        Map<String, Object> mapPram = new HashMap<>(1);
        mapPram.put("productId", productId);
        String urlAppendParm = UrlUtils.getUrlAppendParm(remoteCallProperties.getProductUrl() + ProductApiUrlConstants.GET_PRODUCT, mapPram);
        ResponseEntity<Result> response = restTemplate.getForEntity(urlAppendParm, Result.class, productId);
        if (HttpStatus.OK.equals(response.getStatusCode())) {
            Result<Product> result = response.getBody();
            // java.util.LinkedHashMap cannot be cast to com.zlp.dto.Product
            Product product = dataConverObj(result);
            BeanUtils.copyProperties(product,productResp);
        }
        return productResp;
    }

    private Product dataConverObj(Result<Product> result) {
        return new Gson().fromJson(new Gson().toJson(result.getData()), new TypeToken<Product>(){}.getType());
    }

4.  exchange 方法

@SneakyThrows
    @Override
    public ProductResp getProduct(Long productId) {

        log.info("getProduct.req productId={}", productId);
        ProductResp productResp = new ProductResp();
        Map<String, Object> mapPram = new HashMap<>(1);
        mapPram.put("productId", productId);
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Authorization", UUID.randomUUID().toString());
        HttpEntity<String> requestEntity = new HttpEntity<>(null, requestHeaders);
        // 请求调用
        String urlAppendParm = UrlUtils.getUrlAppendParm(remoteCallProperties.getProductUrl() + ProductApiUrlConstants.GET_PRODUCT, mapPram);
        log.info("getProduct  resp={}", urlAppendParm);
        ResponseEntity<String> response = restTemplate.exchange(urlAppendParm, HttpMethod.GET, requestEntity, String.class);
        HttpStatus statusCode = response.getStatusCode();
        if (HttpStatus.OK.equals(statusCode)) {
            String body = response.getBody();
            if (StringUtils.isNotBlank(body)) {
                String data = JSON.parseObject(body).getString("data");
                productResp = JSON.parseObject(data, ProductResp.class);
                log.info("getProduct.urlAppendParm={}  resp={}", ProductApiUrlConstants.GET_PRODUCT, JSON.toJSONString(productResp));
            }
        } else {
            throw new Exception(String.format("远程调用 [%s] 接口失败!", urlAppendParm));
        }
        return productResp;
    }

5.  postForEntity 方法

 @Override
    public Boolean insertProduct(ProductResp productResp) throws Exception {

        log.info("insertProduct.req productResp={}", JSON.toJSONString(productResp));
        HttpEntity<String> httpEntity = RestTemplateUtils.buildPostForEntity(JSON.toJSONString(productResp));
        String insertPorductUrl = "";
        try {
            insertPorductUrl = remoteCallProperties.getProductUrl() + ProductApiUrlConstants.INSERT_PRODUCT;
            ResponseEntity<String> response = restTemplate.postForEntity(insertPorductUrl, httpEntity, String.class);
            HttpStatus statusCode = response.getStatusCode();
            if (HttpStatus.OK.equals(statusCode)) {
                log.info("insertProduct.resp={}", response.getBody());
            }
        } catch (Exception e) {
            throw new Exception(String.format("远程调用 [%s] 接口失败!", insertPorductUrl));
        }
        return Boolean.TRUE;
    }

三、测试案例

1. RestTemplateController


@RestController
@RequestMapping("remote")
@RequiredArgsConstructor
@Api(value = "远程调用模块", tags = "远程调用模块")
@Slf4j(topic = "RestTemplateController")
public class RestTemplateController {

    private final RemoteService remoteService;

    @GetMapping("/getProduct")
    @ApiOperation(value = "获取商品信息")
    public ProductResp getProduct(@RequestParam (value = "productId") Long productId) {

        return remoteService.getProduct(productId);
    }

    @PostMapping("/insertProduct")
    @ApiOperation(value = "新增商品信息")
    public Boolean insertProduct(@RequestBody ProductResp productResp) throws Exception {

        return remoteService.insertProduct(productResp);
    }

    @GetMapping("/getByProductId")
    @ApiOperation(value = "获取商品信息根据商品ID")
    public ProductResp getByProductId(@RequestParam (value = "productId") Long productId) {

        return remoteService.getByProductId(productId);
    }

}

2. 测试开始

服务名称端口访问地址
product-service (生产者)8300http://127.0.0.1:8300
user-service (调用方)8200http://127.0.0.1:8200

 

swagger 接口测试   http://127.0.0.1:8200/doc.html

/remote/getByProductId

 

 

参考文档
1. springboot 2.0 整合 RestTemplate 与使用教程

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值