RestTemplate Equivalent of cURL PUT - spring

I can access an API with that cURL command:
curl -X PUT -H 'Content-type:application/json' --data-binary '["remaro"]' "http://localhost:4352/mypath"
I want to make it over Spring RestTemplate. My data is stored as String. I tried that but my server returns 400 bad request:
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("\"" + dataVariable + "\"", headers);
restTemplate.put(http://localhost:4352/mypath, entity);
I've also send my variable as:
String dataVariable = "\"remaro\"";
but didn't work. I still get 400 error.

Use RestTemplate.exchange
Look at my example and change accordingly
String url = BASE_URI + "/update/{clusterId}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
ClusterDTO cluster = new ClusterDTO();
cluster.setClusterId(1L);
cluster.setClusterName("ClusterAV");
..........
HttpEntity<ClusterDTO> entity = new HttpEntity<ClusterDTO>(cluster,headers);
ResponseEntity<ClusterDTO> responseEntity = restTemplate.exchange(url, HttpMethod.PUT, entity, ClusterDTO.class,1L);

I've just send it as:
"[\"" + dataVariable + "\"]"
and worked.

Related

How to remove and add new Accept header to Spring boot Rest Template?

I'm consuming a GraphQL Service, it is returning 406 Not Acceptable if the Accept header is text/plain.
It is expecting to Accept as application/json
So I tried override the RestTeamplate Headers. However it seems the Accept header test/plain is always present there. I confirmed this by enabling debug(logging.level.org.springframework.web.client.RestTemplate=DEBUG)
Console
o.s.web.client.RestTemplate: Accept=[text/plain, application/json, application/*+json, */*]
o.s.web.client.RestTemplate: Writing [{products(query: "title:tow*", first: 10) {edges {node {id legacyResourceId title}}}}] as "application/graphql"
Here is the code I tried to override the Accept header
HttpHeaders headers = new HttpHeaders();
RestTemplate restTemplate = new RestTemplate();
headers.add("Content-Type","application/graphql");
headers.setAccept(Collections.singletonList(new MediaType("application","json")));
String content = "{products(query: \"title:tow*\", first: 10) {edges {node {id title}}}}";
HttpEntity<String> requestEntity = new HttpEntity<String>(content, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
I even tried removing the Accept header first(headers.remove("Accept")) and then setAccept but still it doesn't remove it from the log.
Is there anything else need to be done?
Why is it not removing the text/plain from the Accept header?
Why I see multiple options in Accept when I set only one option?

How to turn this POST cURL request into a java code

I have the following cURL request that I want to turn into java code to execute it with spring.
I use it to upload a file, the cURL request works correctly.
curl "https://mywebsite.service-now.com/api/now/attachment/file?table_name=incident&table_sys_id=fa4922f6db3ea30085a0f7871d961999&file_name=test.zip" --request POST --header "Accept:application/json" --header "Authorization:Basic cmVhbHRlc3QyOmJwb3N0QDEyMw==" --header "Content-Type: application/zip" -F "uploadFile=#test.zip"
I will use the following API:
https://docs.servicenow.com/bundle/geneva-servicenow-platform/page/integrate/inbound_rest/reference/r_AttachmentAPI-POST.html
I made a little research and found out that I have to use restTemplate to use 3rd party API.
I also wrote this:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
headers.add("Authorization", "Basic " + encodePassword());
return headers;
(I made the encodePassword method, that is correct. )
I tried a lot of other stuff but it doesn't work
You have to set the content-type header value to MediaType.MULTIPART_FORM_DATA. When this header is set, RestTemplate automatically marshals the file data along with some metadata.
//Headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
//parameter values
// the getTestFile( ) method generates a file on the fly and returns a FileSystemResource
MultiValueMap<String, Object> map= new LinkedMultiValueMap<>();
map.add("file", getTestFile();
...
//create request
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class );

Invalid mimetype exception in Spring boot rest call

I am new to both Spring boot and rest calls.
I am trying to consume a rest service and I do not have any information about that rest API except URL. When I hit that URL from a browser I am getting a response as {key:value}. So, I assumed that it is a JSON response.
I am consuming it in spring boot as follows
restTemplate.getForObject(url, String.class) .
This is giving Invalid mime type "content-type: text/plain; charset=ISO-8859-1": Invalid token character ':' in token "content-type: text"
I assume that this error is because response content type is set to text/plain but it is returning JSON format.
EDIT:
Tried this way but did not work.
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters",headers);
ResponseEntity<String> result = restTemplate.exchange(url,HttpMethod.GET,
entity, String.class);
How to handle and solve it?
You might want to read about the request headers your REST API needs. Content-Type header specifies the media type of the request you're sending to the server. Because you're just getting data from the server you should set the Accept header to the kind of response you want i.e., Accept: application/json.
Unfortunately, you can't set headers using getForObject(). You could try this:
URL url = new URL("Enter the URL of the REST endpoint");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Accept", "application/json");
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuffer content = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
}

Setting Authorization header in Spring RestTemplate

I'm trying to to access a RestAPI-Endpoint with the help of Spring's RestTemplate
public List<Transaction> getTransactions() {
// only a 24h token for the sandbox, so not security critical
// still I replaced the last 10 digits here with 'x' but not in my original code
String authToken = "tylhtvGM6Duy8q0ZBbGaTg2FZefLfyeEeMZvCXlU2bEiinnZcLSACTxxxxxxxxxx";
String encodedAuthToken = Base64.getEncoder().encodeToString(authToken.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer "+encodedAuthToken );
ResponseEntity<TransactionsResponse> response = restTemplate.exchange(
"https://api-sandbox.starlingbank.com/api/v1/transactions",
HttpMethod.GET,
new HttpEntity<>("parameters", headers),
TransactionsResponse.class
);
return response.getBody().getEmbedded().getTransactions();
}
but I get a HttpClientErrorException saying "403 Forbidden".
Long version
Caused by: org.springframework.web.client.HttpClientErrorException: 403 Forbidden
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:79) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:766) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
My code is based on a former stackoverflow thread and a call with the same parameters via Postman is successful:
So what is the problem?
Update
not encoding the authToken makes no difference
headers.add("Authorization", "Bearer tylhtvGM6Duy8q0ZBbGaTg2FZefLfyeEeMZvCXlU2bEiinnZcLSACTxxxxxxxxxx");
still leads to the same HttpClientErrorException: 403 Forbidden
Update2
I answered my question! (short version: UserAgent required. final code in anwser)
this particular server requires an UserAgent! The value can be whatever, but it has to be present!
So the final version is:
public List<Transaction> getTransactions() {
// only a 24h token for the sandbox, so not security critical
// still I replaced the last 10 digits here with 'x' but not in my original code
String authToken = "tylhtvGM6Duy8q0ZBbGaTg2FZefLfyeEeMZvCXlU2bEiinnZcLSACTxxxxxxxxxx";
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("User-Agent", "Spring's RestTemplate" ); // value can be whatever
headers.add("Authorization", "Bearer "+authToken );
ResponseEntity<TransactionsResponse> response = restTemplate.exchange(
"https://api-sandbox.starlingbank.com/api/v1/transactions",
HttpMethod.GET,
new HttpEntity<>("parameters", headers),
TransactionsResponse.class
);
return response.getBody().getEmbedded().getTransactions();
}
If you are using OAuth Bearer tokens for authentication you don't need to encode them prior to making the request. The following line should be sufficient:
headers.add("Authorization", "Bearer " + authToken);
The code you mentioned has Http Basic authentication which consists of sending the credentials as username:password pair encoded with Base64.
You are encoding your token in Base64 and its already encoded, your code is based in this but in this example they are encoding a Basic Authorization header with (user:password) encoded
probe this
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer "+ authToken );
For Bearer authentication Spring has a convenience method setBearerAuth(String token), since version 5.1:
// anonymised: replaced the last 10 digits here with 'x'
String authToken = "tylhtvGM6Duy8q0ZBbGaTg2FZefLfyeEeMZvCXlU2bEiinnZcLSACTxxxxxxxxxx";
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(authToken);

Having trouble recreating a cURL command in a Spring RestTemplate Using Headers

Here's the curl command I'm trying to recreate :
curl https://bannana-pajamas.com/services/data/v20.0/query/?q=BananaQuery -H 'Authorization: Bearer Banana_Token'
This curl command works just fine in my terminal and returns a json file.
Here's my attempt at recreating it in a Spring Rest Template:
//Create a rest template
RestTemplate rest = new RestTemplate();
System.out.println("This here is the token "+Banana_Token);
//Create the headers
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization","Bearer "+Banana_Token);
HttpEntity<String> entity = new HttpEntity<>(headers);
//Create the url
String url = "https://bannana-pajamas.com/services/data/v20.0/query/?q=BananaQuery";
String response;
try{
response = rest.exchange(url, HttpMethod.GET, entity, String.class).toString();
}catch(Exception error){
System.out.println("This still ain't working bro. Imma make this null till you get stuff right");
response = null;
}
return response;
When I run this, I get the following error:
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
I've tried several of the similar answers on this site, but I keep getting that error. I probably missing something very minor.
Anybody have any ideas?
Thanks!

Resources