1. 程式人生 > 其它 >springboot2.0整合RestTemplate

springboot2.0整合RestTemplate

原文地址:https://www.cnblogs.com/eternityz/p/12241380.html

實際整合

獲取restTemplate例項,封裝方法

package com.quant.api.utils.restTemplate;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.client.AsyncRestTemplate;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;

/**
 * @program: api
 * @description:
 * @author: TheEternity Zhang
 * @create: 2019-06-04 18:00
 */
public class RestTemplateUtil {
    /**
     * 傳送表單引數的post請求
     *
     * @param url      請求url
     * @param param    引數
     * @param respType 返回型別
     * @return T
     */
    public static <T> T postForm(String url, Map<String, List<Object>> param, Class<T> respType) {
        return getRestInstance().postForEntity(url, getHttpEntity(param, false), respType).getBody();
    }

    /**
     * 傳送表單引數的非同步post請求
     *
     * @param url      請求url
     * @param callback 回撥介面
     * @param respType 返回型別
     */
    public static <T> void asyncPostForm(String url, Map<String, List<Object>> param,
                                         Class<T> respType, ListenableFutureCallback<ResponseEntity<T>> callback) {
        getAsyncRestInstance().postForEntity(url, getHttpEntity(param, false), respType).addCallback(callback);
    }

    /**
     * 傳送表單有引數get請求
     *
     * @param url      請求url
     * @param param    引數物件
     * @param respType 返回型別
     * @return T
     */
    public static <T> T getForm(String url, Class<T> respType, Map<String,String> param) {
        return getRestInstance().getForEntity(url, respType, param).getBody();
    }

    /**
     * @Description: 傳送表單無引數的get請求
     * @Param: [url, param, respType]
     * @return: T
     * @Author: tonyzhang
     * @Date: 2019-01-18 17:23
     */
    public static <T> T getForm(String url, Class<T> respType) {
        return getRestInstance().getForObject(url, respType);
    }


    /**
     * 獲取HttpEntity例項物件
     *
     * @param param  引數物件
     * @param isJson true 傳送json請求,false傳送表單請求
     * @return HttpEntity
     */
    private static <P> HttpEntity<P> getHttpEntity(P param, boolean isJson) {
        HttpHeaders headers = new HttpHeaders();
        if (isJson) {
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        } else {
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        }

        return new HttpEntity<>(param, headers);
    }

    /*-----------------生產單例物件,方便自定義如何構造物件------------------*/

    private static RestTemplate restInit() {
        //設定連線超時和讀取超時時間
        SimpleClientHttpRequestFactory factory=new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(5000);
        factory.setReadTimeout(5000);
        RestTemplate restTemplate = new RestTemplate(factory);
        FormHttpMessageConverter fastConverter = new FormHttpMessageConverter();
        WxMappingJackson2HttpMessageConverter wmc=new WxMappingJackson2HttpMessageConverter();
        restTemplate.getMessageConverters().add(fastConverter);
        restTemplate.getMessageConverters().add(wmc);
        return restTemplate;
    }



    private static AsyncRestTemplate asyncRestInit() {
        return new AsyncRestTemplate();
    }

    private static RestTemplate getRestInstance() {
        return RestSingle.INSTANCE;
    }

    private static AsyncRestTemplate getAsyncRestInstance() {
        return AsyncRestSingle.INSTANCE;
    }

    private static class RestSingle {
        private static final RestTemplate INSTANCE = restInit();
    }

    private static class AsyncRestSingle {
        private static final AsyncRestTemplate INSTANCE = asyncRestInit();
    }
}

增加一個MessageConverter

package com.quant.api.utils.restTemplate;

import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: api
 * @description: 封裝轉換器, 新增更多型別的支援
 * @author: TheEternity Zhang
 * @create: 2019-06-05 11:13
 */
public class WxMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
    public WxMappingJackson2HttpMessageConverter(){
        List<MediaType> mediaTypes=new ArrayList<>();
        //新增text/html型別的支援
        mediaTypes.add(MediaType.TEXT_HTML);
        //新增text/plain型別的支援.微信介面會用到
        mediaTypes.add(MediaType.TEXT_PLAIN);
        setSupportedMediaTypes(mediaTypes);
    }
}

參考

簡介:

spring框架提供的RestTemplate類可用於在應用中呼叫rest服務,它簡化了與http服務的通訊方式,統一了RESTful的標準,封裝了http連結,我們只需要傳入url及返回值型別即可。相較於之前常用的HttpClient,RestTemplate是一種更優雅的呼叫RESTful服務的方式。

RestTemplate預設依賴JDK提供http連線的能力(HttpURLConnection),如果有需要的話也可以通過setRequestFactory方法替換為例如Apache HttpComponents、Netty或OkHttp等其它HTTP library。

其實spring並沒有真正的去實現底層的http請求(3次握手),而是集成了別的http請求,spring只是在原有的各種http請求進行了規範標準,讓開發者更加簡單易用,底層預設用的是jdk的http請求。

RestTemplate的優缺點:

優點:

連線池、超時時間設定、支援非同步、請求和響應的編解碼

缺點:

依賴別的spring版塊、引數傳遞不靈活

springboot整合RestTemplate:

匯入依賴:(其實他是spring整合好的,這個一般的springboot專案已經由此包了)

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

在啟動類同包下建立RestTemplate.java類

@Configuration
public class RestTemplateConfig {
 
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory){
        return new RestTemplate(factory);
    }
 
    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(15000);
        factory.setReadTimeout(5000);
        return factory;
    }
 
}

然後在Service類中注入使用即可

@Service
public class demoService {
 
    @Autowired
    private RestTemplate restTemplate;
 
    public String get(Integer id){
        return restTemplate.getForObject("http://localhost:8080/user?userId=id",String.class);
    }
}

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

getForEntity

get請求就和正常在瀏覽器url上傳送請求一樣

下面是有引數的get請求

@GetMapping("getForEntity/{id}")
public User getById(@PathVariable(name = "id") String id) {
    ResponseEntity<User> response = restTemplate.getForEntity("http://localhost/get/{id}", User.class, id);
    User user = response.getBody();
    return user;
}

getForObject

getForObject 和 getForEntity 用法幾乎相同,指示返回值返回的是 響應體,省去了我們 再去 getBody()

@GetMapping("getForObject/{id}")
public User getById(@PathVariable(name = "id") String id) {
    User user = restTemplate.getForObject("http://localhost/get/{id}", User.class, id);
    return user;
}

postForEntity

@RequestMapping("saveUser")
public String save(User user) {
    ResponseEntity<String> response = restTemplate.postForEntity("http://localhost/save", user, String.class);
    String body = response.getBody();
    return body;
}

postForObject

用法與 getForObject 一樣

如果遇到 postForObject 方法在 Controller 接受不到引數問題 請參考的的另一篇部落格 :

https://blog.csdn.net/weixin_40461281/article/details/83472648

exchange

@PostMapping("demo")
public void demo(Integer id, String name){

    HttpHeaders headers = new HttpHeaders();//header引數
    headers.add("authorization",Auth);
    headers.setContentType(MediaType.APPLICATION_JSON);

    JSONObject obj = new JSONObject();//放入body中的json引數
    obj.put("userId", id);
    obj.put("name", name);

    HttpEntity<JSONObject> request = new HttpEntity<>(content,headers); //組裝

    ResponseEntity<String> response = template.exchange("http://localhost:8080/demo",HttpMethod.POST,request,String.class);
}

其餘的方法用法也都差不多 , 在此就不細說了