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;
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM