Springboot服务之间调用,使用RestTemplate,使代码更优雅。

本文深入解析Spring的RestTemplate类中的exchange函数,详细介绍其参数意义及使用技巧,包括URL构造、HTTP方法设置、请求实体封装、响应类型指定及参数映射等关键步骤,并提供公司内部代码实例。

        不介绍太多,只介绍实用的,像getObject, getEntity我都不介绍,只介绍一个exchange()函数就够了,最后会附上我们公司的代码。

       下面对RestTemplate的函数做详细说明及使用技巧:

无论GET请求,还是POST请求,exchange参数位置是一样的。
public <T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables)

参数介绍:

1、url: 该参数是请求的url,  有时请求参数在Param或着在Path里面,这时最好的处理方式是使用占位符处理。注:不要直接把参数值直接写上去,直接写上参数值会请求失败。正确写的法如:

http://localhost:8085/userservice/v1/users/query?queryParam={queryParam}

2、method:是调用的方法,如POST, GET。

3、requestEntity:请求的类名,会放入Body中。

4、responseType:返回的类名,返回后,会自动的转换为该类。

5、uriVariables:指的是参数。很多文章都说默认为PATH,其实不是,他是填充占位符用的。在URL中,哪里有占位符,就会填充哪里。如下所示:

(1)Param位置填充。

http://localhost:8085/userservice/v1/users/query?queryParam={queryParam}, map为:

Map<String, String> paramMap = new HashMap<String, String>();
paramMap.put("queryParam", "{\"startPage\":1,\"pageSize\":50}");

自动填充占位{queryParam}.

(2)在Path位置

http://localhost:8085/userservice/v1/users/query/{userId}, 那就会自动填充userId

我的代码如下:

package com.system.http.util;

import com.system.http.entity.ErrorCode;
import com.system.http.entity.RetEntity;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Map.Entry;

/**
 * Http协议的发送类,用于服务之间的调用。
 */
public class HttpSendUtils
{
    public static final int MAP_EMPTY_FLAG = 0;

    public static final int MAP_NOT_EMPTY_FLAG = 1;

    /**
     * Http协议的GET请求。
     *@param url 请求的URL,包含IP,端口号,还有请求的URI。
     *@param sessionId, 服务之间调用的会话id。
     *@param authId ,服务之间调用的签名id。
     *@param paramsMap,请求参数位置在Param中,以Key,Value的形式保存在HashMap中。
     *@return RetEntity, 包含的错误码信息。。
     *@exception  NA
     */
    public static RetEntity httpGet(String url, String sessionId, String authId,
        Map<String, String> paramsMap)
    {
        return sendMessage(url, sessionId, authId, paramsMap, HttpMethod.GET);
    }

    public static RetEntity httpPost(String url, String sessionId, String authId,
        Map<String, String> paramsMap)
    {
        return sendMessage(url, sessionId, authId, paramsMap, HttpMethod.POST);
    }

    private static RetEntity sendMessage(String url, String sessionId, String authId,
        Map<String, String> paramsMap, HttpMethod httpMethod)
    {
        String httpUrl = url;

        //参数标志,标记paramsMap是否为空,0为空。
        int flag = MAP_EMPTY_FLAG;
        if (paramsMap != null && !paramsMap.isEmpty())
        {
            String urlTmp = "?";
            for(Entry<String, String> entry : paramsMap.entrySet())
            {
                urlTmp = urlTmp + entry.getKey() + "=" + "{" + entry.getKey() + "}";
                urlTmp = urlTmp + "&";
            }

            int endIndex = urlTmp.lastIndexOf("&");
            httpUrl = httpUrl + urlTmp.substring(0, endIndex);
            flag = MAP_NOT_EMPTY_FLAG;
        }

        //填充header数据及参数编码格式,防止收到参数为乱码。
        HttpHeaders requestHeaders = new HttpHeaders();
        MediaType mediaType = MediaType.parseMediaType("application/json;charset=UTF-8");
        requestHeaders.setContentType(mediaType);
        if (sessionId != null)
        {
            requestHeaders.add("sessionId", sessionId);
            requestHeaders.add("authId", authId);
        }

        HttpEntity<String> requestEntity = new HttpEntity<String>(null, requestHeaders);
        RestTemplate restTemplate = new RestTemplate();

        ResponseEntity<RetEntity> response = null;
        if (flag == MAP_NOT_EMPTY_FLAG)
        {
            response = restTemplate.exchange(httpUrl, httpMethod,requestEntity, RetEntity.class, paramsMap);
        }
        else
        {
            response = restTemplate.exchange(httpUrl, httpMethod, requestEntity, RetEntity.class);
        }
        RetEntity retValue = response.getBody();
        return retValue;
    }
}

返回类定义 
package com.system.http.entity;
public class RetEntity <T>
{
    private static final long serialVersionUID = 5451109092148890181L;

    private int resultCode;

    private T resultValue;

    private String resultMsg;

    public int getResultCode()
    {
        return resultCode;
    }

    public void setResultCode(int resultCode)
    {
        this.resultCode = resultCode;
    }

    public Object getResultValue()
    {
        return resultValue;
    }

    public void setResultValue(T resultValue)
    {
        this.resultValue = resultValue;
    }

    public String getResultMsg()
    {
        return resultMsg;
    }

    public void setResultMsg(String resultMsg)
    {
        this.resultMsg = resultMsg;
    }

    @Override
    public String toString()
    {
        return "{" +
            "resultCode=" + resultCode +
            ", resultValue=" + resultValue +
            ", resultMsg='" + resultMsg + '\'' +
            '}';
    }
}

方法调用测试类:

import com.system.http.entity.RetEntity;
import com.system.http.util.HttpSendUtils;

import java.util.HashMap;
import java.util.Map;
public class HttpUtilTmp
{
    public static void main(String []args)
    {
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("queryParam", "{\"startPage\":1,\"pageSize\":50}");

        RetEntity retEntity =  null;
        retEntity = HttpSendUtils.httpGet("http://localhost:8085/userservice/v1/users/query",
            "78d5cd86cb9d3caa3adfc7aa2ef221d03e4872dcceb1eb24c0d62be8a6f89366", "6",
            paramMap);
    }
}
### 如何在 Spring Boot 中调用外部 API #### 创建主应用程序类 为了实现对外部API的调用,首先需要定义一个带有`@SpringBootApplication`注解的应用程序入口点。此外,当采用Feign客户端来简化HTTP请求时,则还需要加上`@EnableFeignClients`注解以便开启对Feign的支持。 ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableFeignClients public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } } ``` 此部分代码展示了如何通过简单的几行声明启动了一个具备远程过程调用能力的服务[^2]。 #### 利用 RestTemplate 进行 HTTP 请求 一种简单的方法就是利用内置于Spring Framework中的`RestTemplate`工具来进行各种类型的HTTP操作。下面给出了一段用于发起GET请求并获取JSON格式响应的例子: ```java @Autowired private RestTemplate restTemplate; @GetMapping("/callExternalApi") public ResponseEntity<String> callExternalService() { String url = "https://api.example.com/data"; ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class); return new ResponseEntity<>(responseEntity.getBody(), HttpStatus.OK); } ``` 上述代码片段说明了怎样借助`RestTemplate`对象执行网络通信任务,并返回来自目标URL的数据作为字符串形式的内容给前端使用者[^3]。 #### 定义 Feign Client 实现优雅的接口调用 对于复杂场景下的RESTful服务间通讯而言,推荐使用Netflix开源库——Feign构建面向接口编程风格的HTTP客户机。这不仅提高了代码可读性和维护性,而且减少了样板式的编码工作量。 ```java @FeignClient(name="exampleApiClient", url="https://api.example.com") public interface ExampleApiClient { @GetMapping(value="/data") List<DataModel> getData(); } ``` 这段示例表明了如何声明一个名为`ExampleApiClient`的接口以代表要访问的目标Web服务;同时指定了具体的端点路径以及预期接收的结果集类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值