zoukankan      html  css  js  c++  java
  • Springboot-RestTemplate调用服务实战记录

    springboot内自带的resttemplate可以帮助我们实现远程调用其他服务接口的作用,实际封装了httpclient,将httpclient繁琐的

    配置用springboot特有的配置类来配置,并交给sprinng管理.

    避免在一个项目中频繁创建httpclient对象,造成的堆内存浪费,确保连接对象的单例性.

    优点:配置简单,请求参数灵活.

    缺点:报错需要try-catch手动捕获,不看日志不容易发现问题.没有熔断器,可以根据熔断器状态返回指定错误码,及时发现.

    配置类RestTemplateConfig:

    @Configuration
    public class RestTemplateConfig {
    
        @Bean
        public RestTemplate httpRestTemplate() {
            ClientHttpRequestFactory factory = httpRequestFactory();
            RestTemplate restTemplate = new RestTemplate(factory);
            // 可以添加消息转换
            //restTemplate.setMessageConverters(...);
            // 可以增加拦截器
            //restTemplate.setInterceptors(...);
            return restTemplate;
        }
    
        public ClientHttpRequestFactory httpRequestFactory() {
            return new HttpComponentsClientHttpRequestFactory(restTemplateConfigHttpClient());
        }
    
        public HttpClient restTemplateConfigHttpClient() {
            Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
                    .register("https", SSLConnectionSocketFactory.getSocketFactory())
                    .build();
            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
            // 设置整个连接池最大连接数 根据自己的场景决定
            connectionManager.setMaxTotal(200);
            // 路由是对maxTotal的细分
            connectionManager.setDefaultMaxPerRoute(100);
            RequestConfig requestConfig = RequestConfig.custom()
                    // 服务器返回数据(response)的时间,超过该时间抛出read timeout
                    .setSocketTimeout(10000)
                    // 连接上服务器(握手成功)的时间,超出该时间抛出connect timeout
                    .setConnectTimeout(5000)
                    // 从连接池中获取连接的超时时间,超过该时间未拿到可用连接,
                    // 会抛出org.apache.http.conn.ConnectionPoolTimeoutException:
                    // Timeout waiting for connection from pool
                    .setConnectionRequestTimeout(5000)
                    .build();
            return HttpClientBuilder.create()
                    .setDefaultRequestConfig(requestConfig)
                    .setConnectionManager(connectionManager)
                    .build();
        }
    }

    注入:
    @Autowired
    RestTemplateConfig restTemplateConfig;

    发请求:
    RestTemplate httpRestTemplate = restTemplateConfig.httpRestTemplate();
    try {
        List<Integer> requestBean = new ArrayList<>();
        result.stream().map(a -> {
            requestBean.add(a.getId());
            return a;
        }).collect(Collectors.toList());
        Map map = httpRestTemplate.postForObject(服务url, requestBean, Map.class);
        result = result.stream().map(a -> {
            Iterator iterator = map.keySet().iterator();
            while (iterator.hasNext()) {
                String key = (String) iterator.next();
                Object obj = map.get(key);
                if (String.valueOf(a.getId()).equals(key)) {
                    Integer i = (Integer) obj;
                    a.setCourseCount(i);
                    return a;
                }
            }
            return a;
        }).collect(Collectors.toList());
    } catch (Exception e) {
        System.err.println("调用服务:" + metel2ApiUrl + "查询课程数量异常");
        e.printStackTrace();
    }
    return result;

    get请求方式:用占位符的方式,getForObject后面对应请求头参数顺序
    application.properties如下:
    baidu.translate.api=http://xxxx:80080/translation/add?keyword={1}&product={2}&from={3}&to={4}

    //调百度api转为英文
    private String constructEn(String bucketKey) {
        RestTemplate httpRestTemplate = restTemplateConfig.httpRestTemplate();
        try {
            TransResult requestBean = new TransResult();
            requestBean.setSrc(bucketKey);
            requestBean.setCode("auto");
            requestBean.setMsg("en");
            String transResult = httpRestTemplate.getForObject(baiDuTranslateApi, String.class, bucketKey, "metel", "zh", "en");
            TransResult result = GsonUtil.GsonToBean(transResult, TransResult.class);
            return result.getDst();
        } catch (Exception e) {
            System.err.println("调用服务:" + baiDuTranslateApi + "转换为英文异常");
            e.printStackTrace();
        }
        return null;
    }

     

  • 相关阅读:
    移动端1px问题
    js几种数组排序及sort的实现
    从零开始搭建vue移动端项目到上线
    Maven项目常见错误解决方法汇总
    重读《Java编程思想》
    ubuntu开发环境下eclipse的alt+/自动补全功能不能用
    Linux环境下解压rar文件
    Ubuntu 16.04下deb文件的安装
    优化Ubuntu 16.04系统的几件事
    Ubuntu16.04 安装 “宋体,微软雅黑,Consolas雅黑混合版编程字体” 等 Windows 7 下的字体
  • 原文地址:https://www.cnblogs.com/mlzdev/p/11800140.html
Copyright © 2011-2022 走看看