国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Springboot -- 用更優(yōu)雅的方式發(fā)HTTP請(qǐng)求(RestTemplate詳解)

這篇具有很好參考價(jià)值的文章主要介紹了Springboot -- 用更優(yōu)雅的方式發(fā)HTTP請(qǐng)求(RestTemplate詳解)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

RestTemplateSpring提供的用于訪問(wèn)Rest服務(wù)的客戶(hù)端,RestTemplate提供了多種便捷訪問(wèn)遠(yuǎn)程Http服務(wù)的方法,能夠大大提高客戶(hù)端的編寫(xiě)效率。

我之前的HTTP開(kāi)發(fā)是用apache的HttpClient開(kāi)發(fā),代碼復(fù)雜,還得操心資源回收等。代碼很復(fù)雜,冗余代碼多,稍微截個(gè)圖,這是我封裝好的一個(gè)post請(qǐng)求工具:

springboot http,spring boot,http,java

?

本教程將帶領(lǐng)大家實(shí)現(xiàn)Spring生態(tài)內(nèi)RestTemplate的Get請(qǐng)求Post請(qǐng)求還有exchange指定請(qǐng)求類(lèi)型的實(shí)踐和RestTemplate核心方法源碼的分析,看完你就會(huì)用優(yōu)雅的方式來(lái)發(fā)HTTP請(qǐng)求。

1. 簡(jiǎn)述RestTemplate

Spring用于同步client端的核心類(lèi),簡(jiǎn)化了與http服務(wù)的通信,并滿(mǎn)足RestFul原則,程序代碼可以給它提供URL,并提取結(jié)果。默認(rèn)情況下,RestTemplate默認(rèn)依賴(lài)jdk的HTTP連接工具。當(dāng)然你也可以 通過(guò)setRequestFactory屬性切換到不同的HTTP源,比如Apache HttpComponents、NettyOkHttp。

RestTemplate能大幅簡(jiǎn)化了提交表單數(shù)據(jù)的難度,并且附帶了自動(dòng)轉(zhuǎn)換JSON數(shù)據(jù)的功能,但只有理解了HttpEntity的組成結(jié)構(gòu)(header與body),且理解了與uriVariables之間的差異,才能真正掌握其用法。這一點(diǎn)在Post請(qǐng)求更加突出,下面會(huì)介紹到。

該類(lèi)的入口主要是根據(jù)HTTP的六個(gè)方法制定:

HTTP method RestTemplate methods
DELETE delete
GET getForObject
getForEntity
HEAD headForHeaders
OPTIONS optionsForAllow
POST postForLocation
postForObject
PUT put
any exchange
execute

此外,exchange和excute可以通用上述方法。

在內(nèi)部,RestTemplate默認(rèn)使用HttpMessageConverter實(shí)例將HTTP消息轉(zhuǎn)換成POJO或者從POJO轉(zhuǎn)換成HTTP消息。默認(rèn)情況下會(huì)注冊(cè)主mime類(lèi)型的轉(zhuǎn)換器,但也可以通過(guò)setMessageConverters注冊(cè)其他的轉(zhuǎn)換器。(其實(shí)這點(diǎn)在使用的時(shí)候是察覺(jué)不到的,很多方法有一個(gè)responseType 參數(shù),它讓你傳入一個(gè)響應(yīng)體所映射成的對(duì)象,然后底層用HttpMessageConverter將其做映射)

HttpMessageConverterExtractor<T> responseExtractor =
				new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
復(fù)制代碼

HttpMessageConverter.java源碼:

public interface HttpMessageConverter<T> {
        //指示此轉(zhuǎn)換器是否可以讀取給定的類(lèi)。
	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);

        //指示此轉(zhuǎn)換器是否可以寫(xiě)給定的類(lèi)。
	boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

        //返回List<MediaType>
	List<MediaType> getSupportedMediaTypes();

        //讀取一個(gè)inputMessage
	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;

        //往output message寫(xiě)一個(gè)Object
	void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;

}
復(fù)制代碼

在內(nèi)部,RestTemplate默認(rèn)使用SimpleClientHttpRequestFactoryDefaultResponseErrorHandler來(lái)分別處理HTTP的創(chuàng)建和錯(cuò)誤,但也可以通過(guò)setRequestFactorysetErrorHandler來(lái)覆蓋。

2. get請(qǐng)求實(shí)踐

2.1. getForObject()方法

public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables){}
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
public <T> T getForObject(URI url, Class<T> responseType)
復(fù)制代碼

getForObject()其實(shí)比getForEntity()多包含了將HTTP轉(zhuǎn)成POJO的功能,但是getForObject沒(méi)有處理response的能力。因?yàn)樗玫绞值木褪浅尚偷?code>pojo。省略了很多response的信息。

2.1.1 POJO:

public class Notice {
    private int status;
    private Object msg;
    private List<DataBean> data;
}
public  class DataBean {
  private int noticeId;
  private String noticeTitle;
  private Object noticeImg;
  private long noticeCreateTime;
  private long noticeUpdateTime;
  private String noticeContent;
}
復(fù)制代碼

示例:2.1.2 不帶參的get請(qǐng)求

	/**
	 * 不帶參的get請(qǐng)求
	 */
	@Test
	public void restTemplateGetTest(){
		RestTemplate restTemplate = new RestTemplate();
		Notice notice = restTemplate.getForObject("http://xxx.top/notice/list/1/5"
				, Notice.class);
		System.out.println(notice);
	}
復(fù)制代碼

控制臺(tái)打印:

INFO 19076 --- [           main] c.w.s.c.w.c.HelloControllerTest          
: Started HelloControllerTest in 5.532 seconds (JVM running for 7.233)

Notice{status=200, msg=null, data=[DataBean{noticeId=21, noticeTitle='aaa', noticeImg=null, 
noticeCreateTime=1525292723000, noticeUpdateTime=1525292723000, noticeContent='<p>aaa</p>'}, 
DataBean{noticeId=20, noticeTitle='ahaha', noticeImg=null, noticeCreateTime=1525291492000, 
noticeUpdateTime=1525291492000, noticeContent='<p>ah.......'
復(fù)制代碼

示例:2.1.3 帶參數(shù)的get請(qǐng)求1

Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/{1}/{2}"
				, Notice.class,1,5);
復(fù)制代碼

明眼人一眼能看出是用了占位符{1}。

示例:2.1.4 帶參數(shù)的get請(qǐng)求2

		Map<String,String> map = new HashMap();
		map.put("start","1");
		map.put("page","5");
		Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/"
				, Notice.class,map);
復(fù)制代碼

明眼人一看就是利用map裝載參數(shù),不過(guò)它默認(rèn)解析的是PathVariable的url形式。

2.2 getForEntity()方法

public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables){}
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables){}
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType){}
復(fù)制代碼

與getForObject()方法不同的是返回的是ResponseEntity對(duì)象,如果需要轉(zhuǎn)換成pojo,還需要json工具類(lèi)的引入,這個(gè)按個(gè)人喜好用。不會(huì)解析json的可以百度FastJson或者Jackson等工具類(lèi)。然后我們就研究一下ResponseEntity下面有啥方法。

ResponseEntity、HttpStatus、BodyBuilder結(jié)構(gòu)

ResponseEntity.java

public HttpStatus getStatusCode(){}
public int getStatusCodeValue(){}
public boolean equals(@Nullable Object other) {}
public String toString() {}
public static BodyBuilder status(HttpStatus status) {}
public static BodyBuilder ok() {}
public static <T> ResponseEntity<T> ok(T body) {}
public static BodyBuilder created(URI location) {}
...
復(fù)制代碼

HttpStatus.java

public enum HttpStatus {
public boolean is1xxInformational() {}
public boolean is2xxSuccessful() {}
public boolean is3xxRedirection() {}
public boolean is4xxClientError() {}
public boolean is5xxServerError() {}
public boolean isError() {}
}
復(fù)制代碼

BodyBuilder.java

public interface BodyBuilder extends HeadersBuilder<BodyBuilder> {
    //設(shè)置正文的長(zhǎng)度,以字節(jié)為單位,由Content-Length標(biāo)頭
      BodyBuilder contentLength(long contentLength);
    //設(shè)置body的MediaType 類(lèi)型
      BodyBuilder contentType(MediaType contentType);
    //設(shè)置響應(yīng)實(shí)體的主體并返回它。
      <T> ResponseEntity<T> body(@Nullable T body);
}
復(fù)制代碼

可以看出來(lái),ResponseEntity包含了HttpStatus和BodyBuilder的這些信息,這更方便我們處理response原生的東西。

示例:

@Test
public void rtGetEntity(){
		RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<Notice> entity = restTemplate.getForEntity("http://fantj.top/notice/list/1/5"
                , Notice.class);

        HttpStatus statusCode = entity.getStatusCode();
        System.out.println("statusCode.is2xxSuccessful()"+statusCode.is2xxSuccessful());

        Notice body = entity.getBody();
        System.out.println("entity.getBody()"+body);


        ResponseEntity.BodyBuilder status = ResponseEntity.status(statusCode);
        status.contentLength(100);
        status.body("我在這里添加一句話");
        ResponseEntity<Class<Notice>> body1 = status.body(Notice.class);
        Class<Notice> body2 = body1.getBody();
        System.out.println("body1.toString()"+body1.toString());
    }
復(fù)制代碼
statusCode.is2xxSuccessful()true
entity.getBody()Notice{status=200, msg=null, data=[DataBean{noticeId=21, noticeTitle='aaa', ...
body1.toString()<200 OK,class com.waylau.spring.cloud.weather.pojo.Notice,{Content-Length=[100]}>
復(fù)制代碼

當(dāng)然,還有getHeaders()等方法沒(méi)有舉例。

3. post請(qǐng)求實(shí)踐

同樣的,post請(qǐng)求也有postForObjectpostForEntity。

public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
			throws RestClientException {}
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
			throws RestClientException {}
public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException {}
復(fù)制代碼

示例

我用一個(gè)驗(yàn)證郵箱的接口來(lái)測(cè)試。

@Test
public void rtPostObject(){
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://47.xxx.xxx.96/register/checkEmail";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
    map.add("email", "844072586@qq.com");

    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
    ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class );
    System.out.println(response.getBody());
}
復(fù)制代碼

執(zhí)行結(jié)果:

{"status":500,"msg":"該郵箱已被注冊(cè)","data":null}
復(fù)制代碼

springboot http,spring boot,http,java

?

代碼中,MultiValueMapMap的一個(gè)子類(lèi),它的一個(gè)key可以存儲(chǔ)多個(gè)value,簡(jiǎn)單的看下這個(gè)接口:

public interface MultiValueMap<K, V> extends Map<K, List<V>> {...}
復(fù)制代碼

為什么用MultiValueMap?因?yàn)?code>HttpEntity接受的request類(lèi)型是它。

public HttpEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers){}
我這里只展示它的一個(gè)construct,從它可以看到我們傳入的map是請(qǐng)求體,headers是請(qǐng)求頭。
復(fù)制代碼

為什么用HttpEntity是因?yàn)?code>restTemplate.postForEntity方法雖然表面上接收的request是@Nullable Object request類(lèi)型,但是你追蹤下去會(huì)發(fā)現(xiàn),這個(gè)request是用HttpEntity來(lái)解析。核心代碼如下:

if (requestBody instanceof HttpEntity) {
	this.requestEntity = (HttpEntity<?>) requestBody;
}else if (requestBody != null) {
	this.requestEntity = new HttpEntity<>(requestBody);
}else {
	this.requestEntity = HttpEntity.EMPTY;
}
復(fù)制代碼

我曾嘗試用map來(lái)傳遞參數(shù),編譯不會(huì)報(bào)錯(cuò),但是執(zhí)行不了,是無(wú)效的url request請(qǐng)求(400 ERROR)。其實(shí)這樣的請(qǐng)求方式已經(jīng)滿(mǎn)足post請(qǐng)求了,cookie也是屬于header的一部分??梢园葱枨笤O(shè)置請(qǐng)求頭和請(qǐng)求體。其它方法與之類(lèi)似。

4. 使用exchange指定調(diào)用方式

exchange()方法跟上面的getForObject()、getForEntity()、postForObject()、postForEntity()等方法不同之處在于它可以指定請(qǐng)求的HTTP類(lèi)型。

springboot http,spring boot,http,java

?

但是你會(huì)發(fā)現(xiàn)exchange的方法中似乎都有@Nullable HttpEntity<?> requestEntity這個(gè)參數(shù),這就意味著我們至少要用HttpEntity來(lái)傳遞這個(gè)請(qǐng)求體,之前說(shuō)過(guò)源碼所以建議就使用HttpEntity提高性能。

示例

    @Test
    public void rtExchangeTest() throws JSONException {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://xxx.top/notice/list";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("start",1);
        jsonObj.put("page",5);

        HttpEntity<String> entity = new HttpEntity<>(jsonObj.toString(), headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(url, 
                                          HttpMethod.GET, entity, JSONObject.class);
        System.out.println(exchange.getBody());
    }
復(fù)制代碼

這次可以看到,我使用了JSONObject對(duì)象傳入和返回。

當(dāng)然,HttpMethod方法還有很多,用法類(lèi)似。

5. excute()指定調(diào)用方式

excute()的用法與exchange()大同小異了,它同樣可以指定不同的HttpMethod,不同的是它返回的對(duì)象是響應(yīng)體所映射成的對(duì)象<T>,而不是ResponseEntity<T>

需要強(qiáng)調(diào)的是,execute()方法是以上所有方法的底層調(diào)用。隨便看一個(gè):文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-785611.html

	@Override
	@Nullable
	public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
			throws RestClientException {

		RequestCallback requestCallback = httpEntityCallback(request, responseType);
		HttpMessageConverterExtractor<T> responseExtractor =
				new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
		return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);

到了這里,關(guān)于Springboot -- 用更優(yōu)雅的方式發(fā)HTTP請(qǐng)求(RestTemplate詳解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • RestTemplate.postForEntity 方法進(jìn)行 HTTP POST 請(qǐng)求

    RestTemplate 是 Spring Framework 提供的一個(gè)用于處理 HTTP 請(qǐng)求的客戶(hù)端工具。其中,postForEntity 是 RestTemplate 提供的用于發(fā)送 HTTP POST 請(qǐng)求并返回 ResponseEntity 對(duì)象的方法。 url(String):HTTP POST 請(qǐng)求的目標(biāo)URL。 request(Object):要發(fā)送的請(qǐng)求體數(shù)據(jù),通常是一個(gè)對(duì)象,它將被轉(zhuǎn)換為請(qǐng)

    2024年02月03日
    瀏覽(25)
  • java基于RestTemplate的微服務(wù)發(fā)起http請(qǐng)求

    java基于RestTemplate的微服務(wù)發(fā)起http請(qǐng)求

    實(shí)現(xiàn)的效果

    2024年02月05日
    瀏覽(31)
  • Http請(qǐng)求實(shí)戰(zhàn) ---- 【restTemplate.exchange方法】的簡(jiǎn)單了解應(yīng)用

    RestTemple是Spring提供的用于訪問(wèn)Http請(qǐng)求的客戶(hù)端; 相對(duì)于apache的HTTPClient類(lèi),邏輯繁瑣,代碼復(fù)雜,還要自己編寫(xiě)使用類(lèi)HttpClientUtil,封裝對(duì)應(yīng)的post,get,delete等方法。 RestTemplate可以通過(guò)callback回調(diào)方法和配置HttpMessageConverter 來(lái)定制,用來(lái)把對(duì)象封裝到HTTP請(qǐng)求體,將響應(yīng)信息

    2024年02月13日
    瀏覽(18)
  • java中http請(qǐng)求之restTemplate配置超時(shí)時(shí)間(親測(cè)有用!)

    問(wèn)題: http請(qǐng)求發(fā)起后接收不到返回?cái)?shù)據(jù)?。?!【測(cè)試環(huán)境沒(méi)出問(wèn)題,發(fā)到正式環(huán)境就有問(wèn)題】 項(xiàng)目中通過(guò)restTemplate發(fā)起請(qǐng)求: 打印日志1內(nèi)容為: http請(qǐng)求入?yún)?{data=[{ productStatus=10,skuCode=null}], messageId=ewpfpr1t6ey5r6qj0su0w1h6rt73hr,token=vgvU5EJKuZbuHii7WH6pTINp40ZRicaqLz4dq5P7L6pDzWir8EEGZhCKPuc

    2024年02月11日
    瀏覽(20)
  • SpringBoot RestTemplate詳解

    SpringBoot RestTemplate詳解

    參考自:http://events.jianshu.io/p/477e7a3179c6 大家都知道在SpringBoot中一般適用RestTemplate來(lái)進(jìn)行遠(yuǎn)程調(diào)用,那么SpringBoot中如何默認(rèn)配置RestTemplate,以及如何自定義配置自己的RestTemplate,RestTemplate異步請(qǐng)求如何實(shí)現(xiàn)等 RestTemplate是Spring提供的進(jìn)行遠(yuǎn)程調(diào)用客戶(hù)端 RestTemplate提供了很多遠(yuǎn)

    2024年02月06日
    瀏覽(12)
  • Spring 教程—REST 客戶(hù)端詳解(WebClient 、RestTemplate、HTTP 接口)

    Spring框架為調(diào)用REST端點(diǎn)提供了以下選擇: WebClient?- 非阻塞、響應(yīng)式客戶(hù)端和 fluent API。 RestTemplate?- 帶有模板方法API的同步客戶(hù)端。 HTTP 接口?- 注解式接口,并生成動(dòng)態(tài)代理實(shí)現(xiàn)。 WebClient ?是一個(gè)非阻塞的、響應(yīng)式的客戶(hù)端,用于執(zhí)行HTTP請(qǐng)求。它在5.0中引入,提供了? Re

    2024年02月07日
    瀏覽(50)
  • SpringBoot如何優(yōu)雅接收前端請(qǐng)求參數(shù)

    @RequestParm 我們可以通過(guò) @RequestParm 注解去綁定請(qǐng)求中的參數(shù),將(查詢(xún)參數(shù)或者form表單數(shù)據(jù))綁定到controller的方法參數(shù)中,通俗點(diǎn)說(shuō)就是,我們可以在get請(qǐng)求和post請(qǐng)求中使用改注解,get請(qǐng)求中會(huì)從查詢(xún)參數(shù)中獲取參數(shù),post請(qǐng)求會(huì)從form表單或者查詢(xún)參數(shù)中獲取參數(shù) 默認(rèn)情況

    2024年02月11日
    瀏覽(18)
  • SpringBoot | RestTemplate異常處理器ErrorHandler使用詳解

    SpringBoot | RestTemplate異常處理器ErrorHandler使用詳解

    關(guān)注wx:CodingTechWork ??在代碼開(kāi)發(fā)過(guò)程中,發(fā)現(xiàn)很多地方通過(guò) RestTemplate 調(diào)用了第三方接口,而第三方接口需要根據(jù)某些狀態(tài)碼或者異常進(jìn)行重試調(diào)用,此時(shí),要么在每個(gè)調(diào)用的地方進(jìn)行異常捕獲,然后重試;要么在封裝的 RestTemplate 工具類(lèi)中進(jìn)行統(tǒng)一異常捕獲和封裝。當(dāng)然

    2024年02月12日
    瀏覽(17)
  • HTTP協(xié)議 9 種請(qǐng)求方式用途及區(qū)別(詳解)-- GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT

    關(guān)于HTTP簡(jiǎn)介HTTP菜鳥(niǎo)教程 根據(jù) HTTP 標(biāo)準(zhǔn),HTTP 請(qǐng)求可以使用多種請(qǐng)求方法。 HTTP1.0 定義了三種請(qǐng)求方法: GET, POST 和 HEAD 方法。 HTTP1.1 新增了六種請(qǐng)求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。 序號(hào) 方法 描述用途 1 GET 【 獲取資源 】本質(zhì)就是發(fā)送一個(gè)請(qǐng)求來(lái)取得服務(wù)

    2024年02月02日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包