Spring的RestTemplata使用詳解

來源:互聯網
上載者:User

Spring的RestTemplata使用詳解

spring-web的RestTemplata是對java底層http的封裝,使用RestTemplata使用者可以不再關注底層的串連建立,並且RestTemplata不僅支援Rest規範,還可以定義傳回值物件類型。

在使用中可以直接new一個RestTemplate對象,在我們建立的RestTemplate對象中會有一些返回訊息的訊息轉換器,可以根據返回資料的MediaType尋找對應的轉換器並進行MediaType轉換。自己也可以建立訊息轉換器,建立一個類繼承AbstractGenericHttpMessageConverter<T>類或者實現HttpMessageConverter<T>介面,需要注意的是canRead方法和canWrite方法最好自己做判斷,在writeInternal或write方法中將參數寫入到流,在readInternal或read方法中將返回結果從流的body中擷取並進行類型映射。

RestTemplate對象在底層通過使用java.net包下的實現建立HTTP 要求,可以通過使用ClientHttpRequestFactory指定不同的HTTP請求方式。
ClientHttpRequestFactory介面主要提供了兩種實現方式:

  • 一種是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)建立底層的Http請求串連。
  • 一種方式是使用HttpComponentsClientHttpRequestFactory方式,底層使用HttpClient訪問遠端Http服務,使用HttpClient可以配置串連池和認證等資訊。

RestTemplate預設是使用SimpleClientHttpRequestFactory,內部是調用jdk的HttpConnection,預設逾時為-1,我們可以自己定義逾時時間

SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();//設定連線逾時,單位毫秒factory.setConnectTimeout(5000);//設定讀取逾時,單位毫秒factory.setReadTimeout(10000);RestTemplate restTemplate = new RestTemplate(factory);

使用GET請求: 

  String url = "http://localhost:80/mandy/login.json?account=123456&password=123456";  Result res = restTemplate.getForObject(url, Result.class);

RestTemplate源碼:

  @Override    public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException {        RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);        HttpMessageConverterExtractor<T> responseExtractor =                new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);        return execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables);    } 

使用get請求直接將參數拼接到地址上最好,不知道什麼原因如果使用第三個參數,即便是MultiValueMap類型也不行(網上有人說用MultiValueMap類型可以,我試了不行)

使用POST請求: 

HashMap<String, Object> map = new HashMap<String, Object>();
map.put("name", "測試");
map.put("account", "qwer");
map.put("password", "qwer");
ObjectMapper mapper = new ObjectMapper();
String jsonStr = null;
try {
  jsonStr = mapper.writeValueAsString(map);
} catch (Exception e) {
  e.printStackTrace();
}
//建立HTTP頭部實體,填充頭部資訊,比如資料格式
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);

//建立HTTP實體,可以直接利用構造方法將請求體和要求標頭放進去
HttpEntity<String> httpEntity = new HttpEntity<String>(jsonStr2, httpHeaders);

String url = "http://localhost:80/mandy/user_enable.json";

//調用方法進行請求
Result res2 = restTemplate.postForObject(url, httpEntity, Result.class);

RestTemplate源碼:

  @Override    public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)            throws RestClientException {        RequestCallback requestCallback = httpEntityCallback(request, responseType);        HttpMessageConverterExtractor<T> responseExtractor =                new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);        return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);    } 

使用PUT請求: 

HashMap<String, Object> map = new HashMap<String, Object>();map.put("user_id", "1");map.put("enable", 0);
ObjectMapper mapper = new ObjectMapper();String jsonStr = null;try { jsonStr = mapper.writeValueAsString(map);} catch (JsonProcessingException e) { e.printStackTrace();}
//建立HTTP頭部實體,填充頭部資訊,比如資料格式HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
//建立HTTP實體,可以直接利用構造方法將請求體和要求標頭放進去HttpEntity<String> httpEntity = new HttpEntity<String>(jsonStr, httpHeaders); String url = "http://localhost:80/mandy/user_enable.json";restTemplate.put(url , httpEntity);

 RestTemplate源碼:

  @Override    public void put(String url, Object request, Object... urlVariables) throws RestClientException {        RequestCallback requestCallback = httpEntityCallback(request);        execute(url, HttpMethod.PUT, requestCallback, null, urlVariables);    }

這個方法有個小的缺點就是沒有請求結果的傳回值,如果需要用到傳回值,就不能用這個方法。

如果要使用delete類型的請求,RestTemplate的put方法的參數列中只有下面幾種

@Overridepublic void delete(String url, Object... urlVariables) throws RestClientException {  execute(url, HttpMethod.DELETE, null, null, urlVariables);}@Overridepublic void delete(String url, Map<String, ?> urlVariables) throws RestClientException {  execute(url, HttpMethod.DELETE, null, null, urlVariables);}@Overridepublic void delete(URI url) throws RestClientException {  execute(url, HttpMethod.DELETE, null, null);}

這些方法並沒有給我們參數讓我們放請求體內容,所以如果要直接使用RestTemplate提供的Delete方法,介面必須使用restful風格,將參數放在地址中,通過@PathVariable(value="")註解將參數擷取到。

重點:其實我們可以直接使用RestTemplate的exchange方法,如

@Overridepublic <T> ResponseEntity<T> exchange(String url, HttpMethod method,  HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException {  RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);  ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);  return execute(url, method, requestCallback, responseExtractor, uriVariables);}

這裡只列舉了一個方法,其他的可以看源碼,這個方法可以進行所有類型的請求。

在這個方法中,method參數可以通過HTTPMethod枚舉來進行擷取,requestEntity參數是自己封裝的HttpEntity實體,包含請求體和要求標頭,responseType參數是返回結果的映射類,uriVariables這個參數給我的印象就是雞肋(個人看法),擷取請求返回介面可以通過方法傳回值的getBody()方法擷取。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.