Spring RestTemplate POST Request with URL encoded data - java

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?

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);

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!

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);

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

Related

RestTemplate how remove utf8 from request?

hello i' ve the code from request a sistem but RestTemplate add always utf8 in header
example
POST /v1/documents/validation HTTP/1.1
Accept: application/json
Content-Type: multipart/form-data;charset=UTF8;boundary=gs7Tmph96b0PDkFCrOo9Y7EhtqqV3ok2agluTF
how remove charset=UTF8 ?
this is my code
RestTemplate restTemplate = getRestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("Content-Type", "multipart/form-data");
headers.add("FSE-JWT-Signature", getHashSignature());
headers.add("Authorization", "Bearer " + getBearerToken());
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
FileSystemResource value = new FileSystemResource(new File(fileName));
map.add("file", value);
map.add("requestBody", requestBody.toString());
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);
error
"title":"InvalidRequestContent","status":400,"detail":"Request content not conform to API specification: UTF-8;boundary=Kpj8KEbP1NBn3tLmsWgbj8O6LlcGNzyp60ejoi4A"
By default RestTemplate adds the utf-8 if you use exchange(). I don't know why.
Use postForObject, ie something like this:
String serverEndPoint = "https://httpbin.org/post";
HttpHeaders headers = new HttpHeaders();
headers.setContentType("multipart/form-data");
HttpEntity<Whatever> entity = new HttpEntity<>(whateverObject, headers);
String result = restTemplate.postForObject(serverEndPoint, entity, String.class);

How to pass Headers and request body in POST request?

I am using RestTemplate restTemplate.exchangemethod to POST request to an endpoint. I have OAuth Header and HttpEntity in different file which I want to pass to POST request, in addition to this I also want to pass request to the endpoint.
I was able to successfully pass the headers and request, but not Http entity which contains credentials
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST,
new HttpEntity<>(request, dataRepo.getHeader()), String.class);
Is there any way I can pass all 3 things
HttpEntity
HttpHeaders
request
Here is my code
#RunWith(MockitoJUnitRunner.class)
#TestPropertySource
public class DataTest {
#Inject
private Oauth oauth;
#Mock
private DataRepo dataRepo;
RestTemplate restTemplate = new RestTemplate();
#Qualifier(OAuth2HttpHeadersBuilder.BEAN_NAME)
NewHttpHeader headersBuilder;
#Test
public void testAddEmployeeSuccess() throws URISyntaxException {
URI uri = new URI(url);
Set<String> mockData = Stream.of("A","B").collect(Collectors.toSet());
String onsString = String.join(",", mockData);
Map<String, String> requestBody = new HashMap<>();
requestBody.put("name", onsString);
JSONObject jsonObject = new JSONObject(requestBody);
HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), null);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST,
new HttpEntity<>(request, dataRepo.getHeader()), String.class);
Assert.assertEquals(201, result.getStatusCodeValue());
}
The below code is in NewHttpHeader.java file which contains
Header and HttpEntity
private HttpEntity<MultiValueMap<String,String>> getHttpEntity() {
MultiValueMap<String, String> store = new LinkedMultiValueMap<>();
store.add( "pas", "password" );
store.add( "name", config.getVaultServiceAccountName() );
return new HttpEntity<>( store, getHeader() );
}
private HttpHeaders getHeader() {
HttpHeaders httpHeaders = headersBuilder.build();
httpHeaders.add( HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType() );
httpHeaders.add( HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.getMimeType() );
return httpHeaders;
}
}
Quoting question:
Is there any way I can pass all 3 things
HttpEntity
HttpHeaders
request
Quoting javadoc of HttpEntity:
Represents an HTTP request or response entity, consisting of headers and body.
So the answer to your question is: Yes, you can pass all 3, since the first is nothing but a combination of the other two.
Just merge your two HttpEntity objects.
Before
HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), null);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST,
new HttpEntity<>(request, dataRepo.getHeader()), String.class);
After
HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), dataRepo.getHeader());
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST,
request, String.class);

RestTemplate GET method with path variables

I am trying to make rest call using rest template. I have two header parameters and one path variable to set for the API call. Below is my implementation. But I am receiving HttpServerErrorException: 500 null. Am I setting the path variable in the right way?
Target API: drs/v1/{caseId}
String url = configProperties.getCaseCreateUrl();
if(!StringUtils.isEmpty(url)){
url = url.replace(ApplicationConstants.DOMAIN_NAME,currentUser.domainUrl());
url = url+ caseId;
}
HttpHeaders headers = new HttpHeaders();
headers.set(ApplicationConstants.PS_TOKEN_HEADER, currentUser.getToken());
headers.set(ApplicationConstants.WORGROUP_HEADER, currentUser.getWorkgroupId());
headers.set(ApplicationConstants.DOMAIN_HEADER, currentUser.getDomainId());
headers.set(HttpHeaders.CONTENT_TYPE, MediaType.ALL_VALUE);
HttpsTrustManager.allowAllSSL();
RestTemplate restTemplate = new RestTemplate();
HttpEntity<Map<String, String>> requestEntity = new HttpEntity(null, headers);
ResponseEntity<CaseDetailsDTO> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, CaseDetailsDTO.class);
I am providing a code snippet of RestTemplate GET method with path variables example
public ResponseEntity<List<String>> getNames(long id) {
final String url = "https://some/{id}/name";
//with cookies
ResponseEntity<String> cookie = getCookies();
String set_cookie = cookie.getHeaders().getFirst(HttpHeaders.SET_COOKIE);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Cookie", set_cookie);
HttpEntity request = new HttpEntity(headers);
ResponseEntity<List<String>> response = restTemplate.exchange(url, HttpMethod.GET, request,new ParameterizedTypeReference<List<String>>(){},id);
return response;
}

How To send a Post request with RequetTemplate in Spring

I'm trying to send a post request with spring RequestTemplate but I always get 401 error;
using curl
C:\Users\Latitude E 5410>curl -X POST http://localhost:8080/demo.rest.springsecu
rity.oauth2.0.authentication/oauth/token -H "Accept: application/json" -d "usern
ame=user1&password=user1&client_id=client1&client_secret=client1&grant_type=pass
word&scope=read,write"
{"access_token":"abe9d772-cb29-4bd7-b41a-437e50c10652","token_type":"bearer","re
fresh_token":"bc24f370-fcd8-4ae0-b724-a4241c746b29","expires_in":299844,"scope":
"read,write"}curl: (6) Could not resolve host: application
java code used:
HttpEntity<String> request = new HttpEntity<String>(getHeadersWithClientCredentials());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); //restTemplate.postForObject
//restTemplate.
MultiValueMap<String, String> mvm = new LinkedMultiValueMap<String, String>();
mvm.add("client_id", "client1");
mvm.add("client_secret", "client1");
mvm.add("grant_type", "password");
mvm.add("scope", "read,write,trust");
mvm.add("username", "user1");
mvm.add("password", "user1");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(mvm, requestHeaders);
ResponseEntity<Object> response = restTemplate.exchange("http://localhost:8080/demo.rest.springsecurity.oauth2.0.authentication/oauth/token?", HttpMethod.POST, requestEntity, Object.class);
error I get
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 401 Non-Autorisé
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:475)
at com.geofleet.calculation.TestClient.main(TestClient.java:44)
I found another solution by sending just a post request directly w, I still feel it's a bad practice to do it (passing the parameters in the url), but hey it works,
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> s = restTemplate.exchange("http://localhost:8080/demo.rest.springsecurity.oauth2.0.authentication/oauth/token?username=user1&password=user1&client_id=client1&client_secret=client1&grant_type=password&scope=read", HttpMethod.POST, entity, String.class);
System.out.println(s.getBody().toString());

400 Bad Request with spring REST

I have spring rest service such this
#RequestMapping(method = RequestMethod.POST,
path = "/getdata", consumes = {"multipart/form-data"}, produces = MediaType.APPLICATION_JSON)
public
#ResponseBody
Result getBarcode(#RequestParam("text") String sl,
#RequestParam("imageFile") MultipartFile file) {
... some logic
return new Result(text, message, !processingError);
}
When i call this from http form it works fine and return json text. But when i trying to call this from java code
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("text", "123");
map.add("imageFile", new File("...path to file..."));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.setAccept(MediaType.parseMediaTypes("application/json,text/html,application/xhtml+xml,application/xml"));
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);
ResponseEntity<BcResult> response = restTemplate.exchange("http://localhost:8080/getdata", HttpMethod.POST, requestEntity, BcResult.class);
Then i am getting 400 Bad request error. Can`t figure out what is wrong with this code...
Set your file like this.
map.add("imageFile", new FileSystemResource(new File("...path to file...")));
or like this
map.add("imageFile", new ClassPathResource("...path to file..."));

Categories

Resources