Reputation: 531
I'm new to Spring and trying to do a rest request with RestTemplate. The Java code should do the same as below curl command:
curl --data "name=feature&color=#5843AD" --header "PRIVATE-TOKEN: xyz" "https://someserver.com/api/v3/projects/1/labels"
But the server rejects the RestTemplate with a 400 Bad Request
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("PRIVATE-TOKEN", "xyz");
HttpEntity<String> entity = new HttpEntity<String>("name=feature&color=#5843AD", headers);
ResponseEntity<LabelCreationResponse> response = restTemplate.exchange("https://someserver.com/api/v3/projects/1/labels", HttpMethod.POST, entity, LabelCreationResponse.class);
Can somebody tell me what I'm doing wrong?
Upvotes: 49
Views: 118109
Reputation: 1
my issue, the MessageConverters
contains other converters may converts then entity to json (like FastJsonHttpMessageConverter). So i added the FormHttpMessageConverter to ahead and it works well.
<T> JuheResult<T> postForm(final String url, final MultiValueMap<String, Object> body) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
return exchange(url, HttpMethod.POST, requestEntity);
}
<T> JuheResult<T> exchange(final String url, final HttpMethod method, final HttpEntity<?> requestEntity) {
ResponseEntity<JuheResult<T>> response = restTemplate.exchange(url, method, requestEntity,
new JuheResultTypeReference<>());
logger.debug("调用结果 {}", response.getBody());
return response.getBody();
}
public JuheSupplierServiceImpl(RestTemplateBuilder restTemplateBuilder) {
Duration connectTimeout = Duration.ofSeconds(5);
Duration readTimeout = Duration.ofSeconds(5);
restTemplate = restTemplateBuilder.setConnectTimeout(connectTimeout).setReadTimeout(readTimeout)
.additionalInterceptors(interceptor()).build();
restTemplate.getMessageConverters().add(0, new FormHttpMessageConverter());
}
fastjson prevent resttemplate converting other mediaTypes other than json
Upvotes: 0
Reputation: 5799
It may be a Header issue check if the header is a Valid header, are u referring to "BasicAuth" header?
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
headers.add("Accept", MediaType.APPLICATION_JSON.toString()); //Optional in case server sends back JSON data
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<String, String>();
requestBody.add("name", "feature");
requestBody.add("color", "#5843AD");
HttpEntity formEntity = new HttpEntity<MultiValueMap<String, String>>(requestBody, headers);
ResponseEntity<LabelCreationResponse> response =
restTemplate.exchange("https://example.com/api/request", HttpMethod.POST, formEntity, LabelCreationResponse.class);
Upvotes: 7
Reputation: 4230
I think the problem is that when you try to send data to server didn't set the content type header which should be one of the two: "application/json" or "application/x-www-form-urlencoded" . In your case is: "application/x-www-form-urlencoded" based on your sample params (name and color). This header means "what type of data my client sends to server".
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("PRIVATE-TOKEN", "xyz");
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("name","feature");
map.add("color","#5843AD");
HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
ResponseEntity<LabelCreationResponse> response =
restTemplate.exchange("https://foo/api/v3/projects/1/labels",
HttpMethod.POST,
entity,
LabelCreationResponse.class);
Upvotes: 112
Reputation: 818
You need to set the Content-Type to application/json. Content-Type has to be set in the request. Below is the modified code to set the Content-Type
final String uri = "https://someserver.com/api/v3/projects/1/labels";
String input = "US";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("PRIVATE-TOKEN", "xyz");
HttpEntity<String> request = new HttpEntity<String>(input, headers);
ResponseEntity<LabelCreationResponse> response = restTemplate.postForObject(uri, request, LabelCreationResponse.class);
Here, HttpEntity is constructed with your input i.e "US" and with headers. Let me know if this works, if not then please share the exception. Cheers!
Upvotes: 8