JSON 中 RestTemplate 中的 GET 请求
GET request in RestTemplate in JSON
一个看似超级简单的问题已经困扰了几天:
我正在 application/json
中使用 RestTemplate 发出一个简单的 GET 请求,但我一直收到
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:636)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:592)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:552)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:470)
我做了研究并遵循了这个 tutorial, also I looked at solutions from this POST request via RestTemplate in JSON。但是 none 有帮助,这是我的代码:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
restTemplate.exchange(endpoint, HttpMethod.GET, requestEntity, String.class);
endpoint
是 http://localhost:8080/api/v1/items?itemIds=" + URLEncoder.encode(itemIds, "UTF-8")
在 Postman 中工作正常。
itemIds
是一个 comma-separated 列表,如下所示:
5400028914,5400029138,5400029138,5400029138,5400029138,5400028401,5400028918,5400028076,5400028726
我也尝试使用 getForObject
如下所示:
String result = restTemplate.getForObject(endpoint, String.class);
这给了我这个错误:
org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
我不确定我错过了什么或做错了什么,但相同的端点在 Postman 上运行完美,但唯一的区别是我在 Postman 应用程序中添加了 Content-Type header。
这是我对邮差的要求:
GET /api/v1/items?itemIds=abc%2cdef%2cghi HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Postman-Token: 84790e06-86aa-fa8a-1047-238d6c931a68
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
那么,如果我上面的代码有误,我该如何使用 RestTemplate 正确设置 content-type?
又一次深入研究,我已经启动 Wireshark 来捕获这两个 HTTP 请求,以下是屏幕截图:
来自 Postman 的请求:
来自我的 Java 代码的请求:
我仍然不明白为什么我的 Java 程序抛出 400 而 Postman 的程序正常工作。
非常感谢。
您不需要为 GET 方法设置 "requestEntity",请尝试这样的代码:
public ItemInfo getItemInfo() throws Exception {
String url =
"http://localhost:8080/api/v1/items?itemIds=abc";
ObjectMapper objectMapper = new ObjectMapper();
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
String responseBody = response.getBody();
handlerError(response, url);
try {
return objectMapper.readValue(responseBody, ItemInfo.class);
} catch (IOException exception) {
LOGGER.error("failed to send REST request", exception);
throw new Exception(ErrorCode.NOT_AVAILABLE, url);
}
}
private void handlerError(final ResponseEntity<String> response, final String url) throws Exception {
String responseBody = response.getBody();
try {
if (RestUtil.isError(response.getStatusCode())) {
ObjectMapper objectMapper = new ObjectMapper();
MyInfoError myInfoError = objectMapper.readValue(responseBody, MyInfoError.class);
throw new Exception(infoErreur, ErrorCode.UNKNOWN_CODE_ERROR);
} else if (RestUtil.isNotFound(response.getStatusCode())) {
throw new Exception(ErrorCode.NOT_AVAILABLE, "MyService");
}
} catch (IOException exception) {
LOGGER.error("failed to send REST request", exception);
throw new Exception(ErrorCode.NOT_AVAILABLE, url);
}
}
我把它设为 NULL 因为 GET 方法不发送任何 JSON 请求 body/headers:
restTemplate.exchange(url, HttpMethod.GET, null, String.class);
或:将您的 headers 放入 GET 方法中,如下所示:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<?> requestEntity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
例如 POST 您需要像下面这样设置 requestEntity:
ItemFormRequest request =
new ItemFormRequest(1,"item no", "item name");
HttpEntity<ItemFormRequest> requestEntity = new HttpEntity<>(request);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
String responseBody = response.getBody();
希望对您有所帮助:)
好吧,最终,我的一位 co-workers 帮助我弄清楚了原因,信不信由你,就这么简单:
endpoint
是这样的:
"http:localhost:8080/api/v1/items?itemIds=" + URLEncoder.encode(itemIds, "UTF-8");
不过应该是"http:localhost:8080/api/v1/items?itemIds=" + itemIds;
itemIds
只是一个 comma-separated 列表。
在URL编码器通过"UTF-8"模式编码后,这个comma-separated列表变成itemIds=5400028914%2C5400029138%2C5400029138%2C5400029138%2C5400029138%2C5400028401%2C5400028918%2C5400028076
来自
itemIds=5400028914,5400029138,5400029138,5400029138,5400029138,5400028401,5400028918,5400028076,5400028726
我们不需要URLEncoder来编码URL当使用RestTemplate时,任何人都可以帮助我加深我的理解吗?
谢谢!
一个看似超级简单的问题已经困扰了几天:
我正在 application/json
中使用 RestTemplate 发出一个简单的 GET 请求,但我一直收到
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:636)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:592)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:552)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:470)
我做了研究并遵循了这个 tutorial, also I looked at solutions from this POST request via RestTemplate in JSON。但是 none 有帮助,这是我的代码:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
restTemplate.exchange(endpoint, HttpMethod.GET, requestEntity, String.class);
endpoint
是 http://localhost:8080/api/v1/items?itemIds=" + URLEncoder.encode(itemIds, "UTF-8")
在 Postman 中工作正常。
itemIds
是一个 comma-separated 列表,如下所示:
5400028914,5400029138,5400029138,5400029138,5400029138,5400028401,5400028918,5400028076,5400028726
我也尝试使用 getForObject
如下所示:
String result = restTemplate.getForObject(endpoint, String.class);
这给了我这个错误:
org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
我不确定我错过了什么或做错了什么,但相同的端点在 Postman 上运行完美,但唯一的区别是我在 Postman 应用程序中添加了 Content-Type header。
这是我对邮差的要求:
GET /api/v1/items?itemIds=abc%2cdef%2cghi HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Postman-Token: 84790e06-86aa-fa8a-1047-238d6c931a68
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Content-Type: application/json
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
那么,如果我上面的代码有误,我该如何使用 RestTemplate 正确设置 content-type?
又一次深入研究,我已经启动 Wireshark 来捕获这两个 HTTP 请求,以下是屏幕截图:
来自 Postman 的请求:
来自我的 Java 代码的请求:
我仍然不明白为什么我的 Java 程序抛出 400 而 Postman 的程序正常工作。
非常感谢。
您不需要为 GET 方法设置 "requestEntity",请尝试这样的代码:
public ItemInfo getItemInfo() throws Exception {
String url =
"http://localhost:8080/api/v1/items?itemIds=abc";
ObjectMapper objectMapper = new ObjectMapper();
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
String responseBody = response.getBody();
handlerError(response, url);
try {
return objectMapper.readValue(responseBody, ItemInfo.class);
} catch (IOException exception) {
LOGGER.error("failed to send REST request", exception);
throw new Exception(ErrorCode.NOT_AVAILABLE, url);
}
}
private void handlerError(final ResponseEntity<String> response, final String url) throws Exception {
String responseBody = response.getBody();
try {
if (RestUtil.isError(response.getStatusCode())) {
ObjectMapper objectMapper = new ObjectMapper();
MyInfoError myInfoError = objectMapper.readValue(responseBody, MyInfoError.class);
throw new Exception(infoErreur, ErrorCode.UNKNOWN_CODE_ERROR);
} else if (RestUtil.isNotFound(response.getStatusCode())) {
throw new Exception(ErrorCode.NOT_AVAILABLE, "MyService");
}
} catch (IOException exception) {
LOGGER.error("failed to send REST request", exception);
throw new Exception(ErrorCode.NOT_AVAILABLE, url);
}
}
我把它设为 NULL 因为 GET 方法不发送任何 JSON 请求 body/headers:
restTemplate.exchange(url, HttpMethod.GET, null, String.class);
或:将您的 headers 放入 GET 方法中,如下所示:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<?> requestEntity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
例如 POST 您需要像下面这样设置 requestEntity:
ItemFormRequest request =
new ItemFormRequest(1,"item no", "item name");
HttpEntity<ItemFormRequest> requestEntity = new HttpEntity<>(request);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
String responseBody = response.getBody();
希望对您有所帮助:)
好吧,最终,我的一位 co-workers 帮助我弄清楚了原因,信不信由你,就这么简单:
endpoint
是这样的:
"http:localhost:8080/api/v1/items?itemIds=" + URLEncoder.encode(itemIds, "UTF-8");
不过应该是"http:localhost:8080/api/v1/items?itemIds=" + itemIds;
itemIds
只是一个 comma-separated 列表。
在URL编码器通过"UTF-8"模式编码后,这个comma-separated列表变成itemIds=5400028914%2C5400029138%2C5400029138%2C5400029138%2C5400029138%2C5400028401%2C5400028918%2C5400028076
来自
itemIds=5400028914,5400029138,5400029138,5400029138,5400029138,5400028401,5400028918,5400028076,5400028726
我们不需要URLEncoder来编码URL当使用RestTemplate时,任何人都可以帮助我加深我的理解吗?
谢谢!