SpringBoot - RestTemplate

RestTemplate 

项目中经常会用到 HTTP 请求, 以前都是自己封装的HttpClient,这样其实很浪费效率,最近发现有一个很好用的

东西 RestTemplate,它主要是用来访问 Rest 接口,并且支持传参和接收都用实体类,里面有封装HTTP连接池,

用它可以提高效率,Spring 4.3 及以上版本提供,需要在pom.xml中导入以下包:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
</dependency>

 

SpringBoot 中使用 RestTemplate

 

RestTemplate自己定义的接口使用起来还是有一点麻烦,我们需要自己封装一个 RestBaseTemplate:

import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class RestBaseTemplate extends RestTemplate {

    public RestBaseTemplate() {
        super();
    }

    public RestBaseTemplate(ClientHttpRequestFactory factory) {
        super(factory);
    }

    /**
     *  通用请求接口
     *
     * @param url 请求 URL
     * @param params 请求参数
     * @param responseType 返回类型
     * @param method 请求方式,使用 HttpMethod,默认为 HttpMethod.POST
     * @return 响应的 body 内容
     */
    public <T> T restTemplate(String url, Map<String, Object> params, Class<T> responseType, HttpMethod method) {
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        if (params != null) {
            map.setAll(params);
        }
        switch (method) {
            case POST:
                return this.postForObject(url, map, responseType);
            case GET:
                String getParams;
                if (params == null) {
                    getParams = url;
                } else {
                    getParams = "?" + map.keySet().stream().map(k -> String.format("%s={%s}", k, k))
                            .collect(Collectors.joining("&"));
                }
                return this.getForObject(url + getParams, responseType, params);
            default:
                return this.postForObject(url, map, responseType);
        }
    }

    /**
     * GET 请求,不带参数
     * @param url 请求的URL
     * @return 响应的 body 内容
     */
    public String get(String url) {
        return get(url, new HashMap<>(1));
    }

    /**
     * GET 请求,带参数
     * @param url 请求的URL
     * @param params 请求的参数,不需要做 Encode 处理
     * @return 响应的 body 内容
     */
    public String get(String url, Map<String, Object> params) {
        return restTemplate(url, params, String.class, HttpMethod.GET);
    }

    /**
     * POST 请求,限制返回类型为字符串
     * @param url 请求的 URL
     * @param params 请求参数
     * @return 响应的 body 内容
     */
    public String post(String url, Map<String, Object> params) {
        return restTemplate(url, params, String.class, HttpMethod.POST);
    }

    /**
     * POST 请求
     * @param url 请求的 URL
     * @param params 请求参数
     * @param responseType 返回的数据格式
     * @return 响应的 body 内容
     */
    public <T> T post(String url, Map<String, Object> params, Class<T> responseType) {
        return restTemplate(url, params, responseType, HttpMethod.POST);
    }
}

里面只定义了,我自己目前常使用的几个方法,其他的可以在使用的时候添加,下面是将 RestBaseTemplate 注册到 

Spring 容器中:

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * HTTP 封装类
 */
@Configuration
@ConditionalOnClass(value = {RestTemplate.class, HttpClient.class})
public class RestTemplateConfiguration {

    @Value("${remote.maxTotalConnect:20}")//连接池的最大连接数默认为20
    private int maxTotalConnect;
    @Value("${remote.maxConnectPerRoute:200}")//单个主机的最大连接数
    private int maxConnectPerRoute;
    @Value("${remote.connectTimeout:2000}")//连接超时默认2s
    private int connectTimeout;
    @Value("${remote.readTimeout:10000}")//读取超时默认30s
    private int readTimeout;

    //创建HTTP客户端工厂
    private ClientHttpRequestFactory createFactory() {
        if (this.maxTotalConnect <= 0) {
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            factory.setConnectTimeout(this.connectTimeout);
            factory.setReadTimeout(this.readTimeout);
            return factory;
        }
        HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(this.maxTotalConnect)
                .setMaxConnPerRoute(this.maxConnectPerRoute).build();
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(
                httpClient);
        factory.setConnectTimeout(this.connectTimeout);
        factory.setReadTimeout(this.readTimeout);
        return factory;
    }

    /**
     * 初始化RestTemplate,并加入spring的Bean工厂,由spring统一管理
     */
    @Bean("restBaseTemplate")
    public RestBaseTemplate getRestTemplate() {
        RestBaseTemplate restBaseTemplate = new RestBaseTemplate(this.createFactory());
        List<HttpMessageConverter<?>> converterList = restBaseTemplate.getMessageConverters();
        //加入FastJson转换器
        converterList.add(new FastJsonHttpMessageConverter());
        return restBaseTemplate;
    }
}

接下来可以根据不同的运行环境,在application.properties中配置不同的连接池配置,在代码里面直接使

用 @Autowired 引入就可以使用。

@RestController
public class TestHttpApi implements Serializable {

    @Autowired
    private RestBaseTemplate restBaseTemplate;

    @RequestMapping("test")
    public void testRestTemplate() {
        String result = restBaseTemplate.get("http://www.baidu.com/");
        System.out.println(result);
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demon-HY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值