相同的參數(接口的入參json打印在日志了)在PostMan中返回預期的數據,但使用RestTemplate時去提示信息錯誤(參數中漢字)。
這種情況,搞得懷疑對RestTemplate的理解了
使用RestTemplate的代碼如下:
JSONObject reqVO = new JSONObject(12); reqVO.put("token", smsConfig.getToken()); reqVO.put("phones", new String[]{mobile.toString()});//一個或多個號碼數組,一次不能超過10 reqVO.put("content", "content,包含漢字"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); String jsonPost = reqVO.toString(); HttpEntity<String> entity = new HttpEntity<>(jsonPost, headers); ResponseEntity<String> responseEntity = restTemplate.postForEntity(smsConfig.getUrl(), entity, String.class); String body = responseEntity.getBody();
解決辦法,通過wireshark抓包:
使用Postman發送時情況:
使用上面的代碼調接口時的http數據情況:
/** * A String equivalent of {@link MediaType#APPLICATION_JSON}. * @see #APPLICATION_JSON_UTF8_VALUE */ public final static String APPLICATION_JSON_VALUE = "application/json"; /** * Public constant media type for {@code application/json;charset=UTF-8}. */ public final static MediaType APPLICATION_JSON_UTF8;
只更改上面中設置Content-type的這行代碼,更改后的:
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
上面 wireshark的過濾器:
ip.dst==目標接口的ip地址 and tcp.port==80 and http.request.method="POST"
Tips:
wireshark是非常流行的網絡封包分析軟件,功能十分強大。可以截取各種網絡封包,顯示網絡封包的詳細信息。使用wireshark的人必須了解網絡協議,否則就看不懂wireshark了。
為了安全考慮,wireshark只能查看封包,而不能修改封包的內容,或者發送封包。
wireshark能獲取HTTP,也能獲取HTTPS,但是不能解密HTTPS,所以wireshark看不懂HTTPS中的內容,總結,如果是處理HTTP,HTTPS 還是用Fiddler, 其他協議比如TCP,UDP 就用wireshark.
過濾表達式的規則
表達式規則
1. 協議過濾
比如TCP,只顯示TCP協議。
2. IP 過濾
比如 ip.src ==192.168.1.102 顯示源地址為192.168.1.102,
ip.dst==192.168.1.102, 目標地址為192.168.1.102
3. 端口過濾
tcp.port ==80, 端口為80的
tcp.srcport == 80, 只顯示TCP協議的願端口為80的。
4. Http模式過濾
http.request.method=="GET", 只顯示HTTP GET方法的。
5. 邏輯運算符為 AND/ OR
常用的過濾表達式
過濾表達式 | 用途 |
http | 只查看HTTP協議的記錄 |
ip.src ==192.168.1.102 or ip.dst==192.168.1.102 | 源地址或者目標地址是192.168.1.102 |
封包列表(Packet List Pane)
封包列表的面板中顯示,編號,時間戳,源地址,目標地址,協議,長度,以及封包信息。 你可以看到不同的協議用了不同的顏色顯示。
http://blog.csdn.net/holandstone/article/details/47026213
restTemplate使用及中文亂碼問題
public <T> T restTemplate(String url, Map<String,T> params, Class<T> var, HttpMethod method) { RestTemplate restTemplate = new RestTemplate(); FormHttpMessageConverter fc = new FormHttpMessageConverter(); StringHttpMessageConverter s = new StringHttpMessageConverter(StandardCharsets.UTF_8); List<HttpMessageConverter<?>> partConverters = new ArrayList<HttpMessageConverter<?>>(); partConverters.add(s); partConverters.add(new ResourceHttpMessageConverter()); fc.setPartConverters(partConverters); restTemplate.getMessageConverters().addAll(Arrays.asList(fc, new MappingJackson2HttpMessageConverter())); MultiValueMap<String, T> map = new LinkedMultiValueMap<>(); map.setAll(params); switch (method) { case POST: return restTemplate.postForObject(url, map, var); case GET: String getParams = "?" + map.keySet().stream().map(k -> String.format("%s={%s}", k, k)).collect(Collectors.joining("&")); return restTemplate.getForObject(url + getParams, var, params); default: return restTemplate.postForObject(url, map, var); } }
所要注意的是get請求要求我們對URL中參數用占位符封裝,user/getUser?userId={userId}&fe=
{fe},就像這樣,所以我在封裝get請求時有一個拼接URL的操作。
http://blog.csdn.net/u013979547/article/details/52564316
問題描述
我沒有找到任何例子來解決我的問題,所以我想請你幫忙。我不能簡單地使用JSON中的RestTemplate對象發送POST請求
每次我得到org.springframework.web.client.HttpClientErrorException:415不支持的媒體類型
我以這種方式使用RestTemplate:
... restTemplate = new RestTemplate(); List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>(); list.add(new MappingJacksonHttpMessageConverter()); restTemplate.setMessageConverters(list); ... Payment payment= new Payment("Aa4bhs"); Payment res = restTemplate.postForObject("http://localhost:8080/aurest/rest/payment", payment, Payment.class);
我的錯是什么
最佳解決方案
這種技術對我有用:
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers); restTemplate.put(uRL, entity);
我希望這有幫助
KD
次佳解決方案
我一直在使用具有JSONObjects的rest模板,如下所示:
// create request body JSONObject request = new JSONObject(); request.put("username", name); request.put("password", password); // set headers HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers); // send request and parse result ResponseEntity<String> loginResponse = restTemplate .exchange(urlString, HttpMethod.POST, entity, String.class); if (loginResponse.getStatusCode() == HttpStatus.OK) { JSONObject userJson = new JSONObject(loginResponse.getBody()); } else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) { // nono... bad credentials }
第三種解決方案
嘗試調試REST端點時,我遇到這個問題。這是使用Spring的RestTemplate類來創建我使用的POST請求的一個基本示例。我花了很長時間把不同地方的代碼整理成一個工作版本。
RestTemplate restTemplate = new RestTemplate(); String url = "endpoint url"; String requestJson = "{\"queriedQuestion\":\"Is there pain in your hand?\"}"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers); String answer = restTemplate.postForObject(url, entity, String.class); System.out.println(answer);
特定的JSON解析器我的休息終點是使用圍繞字段名稱的雙引號,這就是為什么我在我的requestJson String中轉義了雙引號。
第四種方案
根據指定的here我想你需要添加一個messageConverter
為MappingJacksonHttpMessageConverter
第五種方案
“415不支持的媒體類型”錯誤告訴您服務器將不接受您的POST請求。您的請求絕對不錯,這是mis-configured的服務器。
MappingJacksonHttpMessageConverter
會自動將請求content-type標頭設置為application/json
,我的猜測是您的服務器拒絕了。你沒有告訴我們任何關於你的服務器設置,所以我不能真的建議你。
第六種方案
如果您使用的是Spring 3.0,則可以避免使用org.springframework.web.client.HttpClientErrorException:415不支持的介質類型異常的簡單方法是將jackson jar文件包含在類路徑中,並使用mvc:annotation-driven
config元素。 As specified here。
我正在拉我的頭發,試圖找出為什么mvc-ajax應用程序工作沒有任何特殊的配置為MappingJacksonHttpMessageConverter
。如果你仔細閱讀我所鏈接的文章:
Underneath the covers, Spring MVC delegates to a HttpMessageConverter to perform the serialization. In this case, Spring MVC invokes a MappingJacksonHttpMessageConverter built on the Jackson JSON processor. This implementation is enabled automatically when you use the mvc:annotation-driven configuration element with Jackson present in your classpath.
參考文獻
注:本文內容整合自google/baidu/bing輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:gxnotes#qq.com(#替換為@)。
https://gxnotes.com/article/61287.html
http://www.cnblogs.com/rollenholt/p/3894117.html
RestTemplate
這篇文章打算介紹一下Spring的RestTemplate
。我這邊以前設計到http交互的,之前一直采用的是Apache HttpComponents
。后來發現Spring框架中已經為我們封裝好了這個框架。因此我們就不需要直接使用下面這種稍微底層一點的方式來實現我們的功能:
String uri = "http://example.com/hotels/1/bookings"; PostMethod post = new PostMethod(uri); String request = // create booking request content post.setRequestEntity(new StringRequestEntity(request)); httpClient.executeMethod(post); if (HttpStatus.SC_CREATED == post.getStatusCode()) { Header location = post.getRequestHeader("Location"); if (location != null) { System.out.println("Created new booking at :" + location.getValue()); } }
Spring的RestTemplate提供了一些更高級別的方法來滿足我們的功能,比如對HTTP Method的支持:
雖然Spring的RestTemplate提供了對這么多HTTP method的支持,但是從個人工作角度來說,常用的也就get和post這兩種方式,有興趣的朋友可以自己翻看一下源碼。
RestTemplate的使用
RestTemplate有兩個構造方法,分別是:
public RestTemplate() { /** ...初始化過程 */ } public RestTemplate(ClientHttpRequestFactory requestFactory) { this(); setRequestFactory(requestFactory); }
其中,第二個構造方法中可以傳入ClientHttpRequestFactory參數,第一個進行默認初始化,因為我們經常需要對請求超時進行設置並能夠對超時進行后續處理,而第一個構造方法,我們無法控制超時時間,第二個構造中的ClientHttpRequestFactory接口的實現類中存在timeout屬性,因此選用第二個構造方法。
在spring配置文件中進行如下配置:
<!-- 配置RestTemplate -->
<!--Http client Factory-->
<bean id="httpClientFactory" class="org.springframework.http.client.SimpleClientHttpRequestFactory"> <property name="connectTimeout" value="${connectTimeout}"/> <property name="readTimeout" value="${readTimeout}"/> </bean> <!--RestTemplate--> <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> <constructor-arg ref="httpClientFactory"/> </bean>
當然也可以直接使用:
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setConnectTimeout(1000); requestFactory.setReadTimeout(1000); RestTemplate restTemplate = new RestTemplate(requestFactory);
注意:ClientHttpRequestFactory 接口有4個實現類,分別是:
- AbstractClientHttpRequestFactoryWrapper 用來裝配其他request factory的抽象類。
- CommonsClientHttpRequestFactory 允許用戶配置帶有認證和http連接池的httpclient,已廢棄,推薦用HttpComponentsClientHttpRequestFactory。
- HttpComponentsClientHttpRequestFactory 同2.
- SimpleClientHttpRequestFactory 接口的一個簡單實現,可配置proxy,connectTimeout,readTimeout等參數。
GET
Spring的RestTemplate提供了許多的支持,這里僅僅列出常用的接口:
public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> urlVariables) throws RestClientException public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException
對於GET請求來說,我一般常用的幾種形式如下:
String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", String.class,"42", "21");
或者下面這張形式:
Map<String, String> vars = Collections.singletonMap("hotel", "42"); String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);
以及:java String message = restTemplate.getForObject("http://localhost:8080/yongbarservice/appstore/appgoods/restTemplate?name=zhaoshijie&id=80", String.class );
他這種做法參考了uri-templates
(https://code.google.com/p/uri-templates/)這個項目。
POST
Spring的RestTemplate對post的常用接口:
public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables) throws RestClientException public <T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException public <T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException
我一般常用的方法為:
MultiValueMap<String, String> bodyMap = new LinkedMultiValueMap<String, String>(); bodyMap.setAll(urlVariables); ResponseClass responseClass = restTemplate.postForObject(CAR_CES_URL, bodyMap, ResponseClass.class);
以及:
HttpHeaders headers = new HttpHeaders(); headers.add("X-Auth-Token", "e348bc22-5efa-4299-9142-529f07a18ac9"); MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>(); postParameters.add("owner", "11"); postParameters.add("subdomain", "aoa"); postParameters.add("comment", ""); HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(postParameters, headers); ParseResultVo exchange = null; try { exchange = restTemplate.postForObject("http://l-dnsutil1.ops.beta.cn6.qunar.com:10085/v1/cnames/tts.piao", requestEntity, ParseResultVo.class); logger.info(exchange.toString()); } catch (RestClientException e) { logger.info("。。。。"); }
以及:
DomainParam domainParam = new DomainParam(); domainParam.setCustomerId(1); //... logger.info("...."); restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter()); restTemplate.getMessageConverters().add(new StringHttpMessageConverter()); String responseResult = restTemplate.postForObject(url, domainParam, String.class);
其他
PUT
方式:
restTemplate.put("http://localhost:8080/yongbarservice/appstore/appgoods/restTemplate?name=zhaoshijie&id=80" ,null);
DELETE
方式
//delete方法(注意:delete方法沒有返回值,說明,id=0這個參數在服務器端可以不定義該參數,直接使用request獲取) // restTemplate.delete("http://localhost:8080/yongbarservice/appstore/appgoods/deleteranking?id=0");
參考資料:
http://www.cnblogs.com/fx2008/p/4010875.html
1. Overview
In this tutorial, we’re going to illustrate the broad range of operations where the Spring REST Client – RestTemplate – can be used, and used well.
For the API side of all examples, we’ll be running the RESTful service from here.
Further reading:
Basic Authentication with the RestTemplate
How to do Basic Authentication with the Spring RestTemplate.
RestTemplate with Digest Authentication
How to set up Digest Authentication for the Spring RestTemplate using HttpClient 4.
HttpClient 4 Tutorial
Comprehensive Guide to the Apache HttpClient - start with basic usage and make your way though the advanced scenarios.
2. Use GET to Retrieve Resources
2.1. Get Plain JSON
Let’s start simple and talk about GET requests – with a quick example using the getForEntity() API:
1
2
3
4
5
6
|
RestTemplate restTemplate =
new
RestTemplate();
String fooResourceUrl
ResponseEntity<String> response
= restTemplate.getForEntity(fooResourceUrl +
"/1"
, String.
class
);
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
|
Notice that we have full access to the HTTP response – so we can do things like checking the status code to make sure the operation was actually successful, or work with the actual body of the response:
1
2
3
4
|
ObjectMapper mapper =
new
ObjectMapper();
JsonNode root = mapper.readTree(response.getBody());
JsonNode name = root.path(
"name"
);
assertThat(name.asText(), notNullValue());
|
We’re working with the response body as a standard String here – and using Jackson (and the JSON node structure that Jackson provides) to verify some details.
2.1. Retrieving POJO Instead of JSON
We can also map the response directly to a Resource DTO – for example:
1
2
3
4
5
6
|
public
class
Foo
implements
Serializable {
private
long
id;
private
String name;
// standard getters and setters
}
|
Now – we can simply use the getForObject API in the template:
1
2
3
4
|
Foo foo = restTemplate
.getForObject(fooResourceUrl +
"/1"
, Foo.
class
);
assertThat(foo.getName(), notNullValue());
assertThat(foo.getId(), is(1L));
|
3. Use HEAD to Retrieve Headers
Let’s now have a quick look at using HEAD before moving on to the more common methods – we’re going to be using the headForHeaders() API here:
1
2
3
4
|
HttpHeaders httpHeaders = restTemplate
.headForHeaders(fooResourceUrl);
assertTrue(httpHeaders.getContentType()
.includes(MediaType.APPLICATION_JSON));
|
4. Use POST to Create a Resource
In order to create a new Resource in the API – we can make good use of the postForLocation(), postForObject() or postForEntity() APIs.
The first returns the URI of the newly created Resource while the second returns the Resource itself.
4.1. The postForObject API
1
2
3
4
5
6
7
|
ClientHttpRequestFactory requestFactory = getClientHttpRequestFactory();
RestTemplate restTemplate =
new
RestTemplate(requestFactory);
HttpEntity<Foo> request =
new
HttpEntity<>(
new
Foo(
"bar"
));
Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.
class
);
assertThat(foo, notNullValue());
assertThat(foo.getName(), is(
"bar"
));
|
4.2. The postForLocation API
Similarly, let’s have a look at the operation that – instead of returning the full Resource, just returns the Location of that newly created Resource:
1
2
3
4
|
HttpEntity<Foo> request =
new
HttpEntity<>(
new
Foo(
"bar"
));
URI location = restTemplate
.postForLocation(fooResourceUrl, request);
assertThat(location, notNullValue());
|
4.3. The exchange API
Finally, let’s have a look at how to do a POST with the more generic exchange API:
1
2
3
4
5
6
7
8
9
10
11
|
RestTemplate restTemplate =
new
RestTemplate();
HttpEntity<Foo> request =
new
HttpEntity<>(
new
Foo(
"bar"
));
ResponseEntity<Foo> response = restTemplate
.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.
class
);
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
Foo foo = response.getBody();
assertThat(foo, notNullValue());
assertThat(foo.getName(), is(
"bar"
));
|
5. Use OPTIONS to get Allowed Operations
Next, we’re going to have a quick look at using an OPTIONS request and exploring the allowed operations on a specific URI using this kind of request; the API is optionsForAllow:
1
2
3
4
|
Set<HttpMethod> optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl);
HttpMethod[] supportedMethods
= {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE};
assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods)));
|
6. Use PUT to Update a Resource
Next, we’ll start looking at PUT – and more specifically the exchange API for this operation, because of the template.put API is pretty straightforward.
6.1. Simple PUT with .exchange
We’ll start with a simple PUT operation against the API – and keep in mind that the operation isn’t returning anybody back to the client:
1
2
3
4
5
6
|
Foo updatedInstance =
new
Foo(
"newName"
);
updatedInstance.setId(createResponse.getBody().getId());
String resourceUrl =
fooResourceUrl +
'/'
+ createResponse.getBody().getId();
HttpEntity<Foo> requestUpdate =
new
HttpEntity<>(updatedInstance, headers);
template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.
class
);
|
6.2. PUT with .exchange and a Request Callback
Next, we’re going to be using a request callback to issue a PUT.
Let’s make sure we prepare the callback – where we can set all the headers we need as well as a request body:
1
2
3
4
5
6
7
8
9
10
|
RequestCallback requestCallback(
final
Foo updatedInstance) {
return
clientHttpRequest -> {
ObjectMapper mapper =
new
ObjectMapper();
mapper.writeValue(clientHttpRequest.getBody(), updatedInstance);
clientHttpRequest.getHeaders().add(
HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
clientHttpRequest.getHeaders().add(
HttpHeaders.AUTHORIZATION,
"Basic "
+ getBase64EncodedLogPass());
};
}
|
Next, we create the Resource with POST request:
1
2
3
|
ResponseEntity<Foo> response = restTemplate
.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.
class
);
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
|
And then we update the Resource:
1
2
3
4
5
6
7
8
|
Foo updatedInstance =
new
Foo(
"newName"
);
updatedInstance.setId(response.getBody().getId());
String resourceUrl =fooResourceUrl +
'/'
+ response.getBody().getId();
restTemplate.execute(
resourceUrl,
HttpMethod.PUT,
requestCallback(updatedInstance),
clientHttpResponse ->
null
);
|
7. Use DELETE to Remove a Resource
To remove an existing Resource we’ll make short work of the delete() API:
1
2
|
String entityUrl = fooResourceUrl +
"/"
+ existingResource.getId();
restTemplate.delete(entityUrl);
|
8. Configure Timeout
We can configure RestTemplate to time out by simply using ClientHttpRequestFactory – as follows:
1
2
3
4
5
6
7
8
9
|
RestTemplate restTemplate =
new
RestTemplate(getClientHttpRequestFactory());
private
ClientHttpRequestFactory getClientHttpRequestFactory() {
int
timeout =
5000
;
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
=
new
HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout(timeout);
return
clientHttpRequestFactory;
}
|
And we can use HttpClient for further configuration options – as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
private
ClientHttpRequestFactory getClientHttpRequestFactory() {
int
timeout =
5000
;
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(timeout)
.setConnectionRequestTimeout(timeout)
.setSocketTimeout(timeout)
.build();
CloseableHttpClient client = HttpClientBuilder
.create()
.setDefaultRequestConfig(config)
.build();
return
new
HttpComponentsClientHttpRequestFactory(client);
}
|
9. Conclusion
We went over the main HTTP Verbs, using RestTemplate to orchestrate requests using all of these.
If you want to dig into how to do authentication with the template – check out my write-up on Basic Auth with RestTemplate.
The implementation of all these examples and code snippets can be found in my GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.
http://www.baeldung.com/rest-template
RestTemplate:
設置代理
Configure RestTemplate to Use a Proxy
As described in Section 33.1, “RestTemplate Customization”, you can use a RestTemplateCustomizer with RestTemplateBuilder to build a customized RestTemplate.
This is the recommended approach for creating a RestTemplate configured to use a proxy.
The exact details of the proxy configuration depend on the underlying client request factory that is being used.
The following example configures HttpComponentsClientRequestFactory with an HttpClient that uses a proxy for all hosts except 192.168.0.5:
static class ProxyCustomizer implements RestTemplateCustomizer { @Override public void customize(RestTemplate restTemplate) { HttpHost proxy = new HttpHost("proxy.example.com"); HttpClient httpClient = HttpClientBuilder.create() .setRoutePlanner(new DefaultProxyRoutePlanner(proxy) { @Override public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context) throws HttpException { if (target.getHostName().equals("192.168.0.5")) { return null; } return super.determineProxy(target, request, context); } }).build(); restTemplate.setRequestFactory( new HttpComponentsClientHttpRequestFactory(httpClient)); } }
https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference/htmlsingle/#howto-reload-thymeleaf-content
RestTempate中處理返回值中帶有泛型的API:
resttemplate是一個很方便的HTTP客戶端,但是當返回的數據類型是泛型時會報錯
//一般用法,通過postForObject獲取結果 REST_TEMPLATE.postForObject(supplier.getApi(),param,Result.class) //Result.java public class Result<T> { private int code; private List<T> data; ... } //報錯 java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to xxx
原因:
postForObject無法知道具體的實例化類型,解析為了LinkedHashMap
解決方法,使用exchange方法替代:
Map<String,Object> param = new HashedMap(); param.put("key","value");//傳入參數 parameterizedTypeReference = new ParameterizedTypeReference<Result<XXX>>(){}; //XXX為實例化的類型 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<>(new Gson().toJson(param),headers); ResponseEntity<YunResult<Instance>> result = REST_TEMPLATE.exchange(url, HttpMethod.POST, entity, parameterizedTypeReference);
鏈接:https://www.jianshu.com/p/597066dec24d