sending GET request via REST template with JSON request body getting failed with binding binding element must be a struct error? - spring-boot

I am trying to send a GET request using REST Template with a JSON request body, but the request is failing with error,
processing
failedorg.springframework.web.client.HttpServerErrorException$InternalServerError:
500 Internal Server Error: [code=400, message=binding element must be
a struct]
I have tried hitting the endpoint using the insomnia and the request is going through successfully, There I have put 2 headers
1. Content-Type - application/json
2. Authorization - Bearer ******
And the JSON body.
My code in spring boot looks like this.
ResponseEntity<String> responseObject = null;
String URL = "https://myurl/endpoint";
String requestBody = "{\"requestType\":\"status\"}";
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization","Bearer ***");
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity httpEntity = new HttpEntity<>(body,headers);
System.out.println(httpEntity+" httpEntity");
System.out.println(headers+" headers");
responseObject = restTemplate.exchange(URL, HttpMethod.GET, httpEntity, String.class);
The sout for httpentity and header looks like this
httpEntity
<{"requestType":"status"},[Authorization:"Bearer *******************", Content-Type:"application/json"]>
headers
[Authorization:"Bearer *************************", Content-Type:"application/json"]
Also when I am trying to send a request without the body to another endpoint using rest template, that is getting executed successfully, so I think something with the way I am sending the body has to do with the error.

rest template doesn't support get request with body . for more details you can refer this article.
If you are on Java 11 I would suggest you to use java.net.HttpClient which will fulfill your need.

Related

Get response body in response 400 HTTP Rest Template

I'm using Rest template to make a request to a service. But I'm getting response code 400 and response null. I made the same call by postman, with the same parameters and I'm getting the body response. How do I get the body response?
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add("Authorization", "Bearer " + token);
headers.add("kms_credencial", parametros.get("KMS_CREDENCIAL"));
headers.add("kms_credencial_tipo", parametros.get("KMS_CREDENCIAL_TIPO"));
HttpEntity<MultiValueMap<String,Object>> entity =
new HttpEntity<MultiValueMap<String, Object>>(request, headers);
ResponseEntity<String> response = null;
response = restTemplate.exchange(parametros.get("SERVICE_HUB2_BASE_URL") + "/fw/v1/pdf/kms/lote/assinaturas",
HttpMethod.POST, entity, String.class);
Could someone tell me what's wrong?
I had the same problem.
From what I've seen, ResteTemplate doesn't accept an error response (400, 500) with a 'large' body.
I still haven't found a solution, but I'm studying the parameters that the method accepts to see if any of them allows receiving a larger body

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?

Outh2 Access Token Exception

I am implementing Outh2 for authentication in spring boot application.I am getting the authorization code successfully but when i am making post request to token url by rest template it is giving me exception 400 bad Request.By this exception i am not able to identify the issue.Below is my code.
ResponseEntity<String> response = null;
System.out.println("Authorization Ccode------" + code);
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> request = new HttpEntity<String>(headers);
String access_token_url = "https://www.googleapis.com/oauth2/v3/token";
access_token_url += "?code=" + code;
access_token_url += "&client_id =487786082511-ta7fnptb8dnd4lbq9lphbtbpll9eo1it.apps.googleusercontent.com";
access_token_url += "&client_secret =fS4KHLUUMOm-lYu8QtDOFcDV";
access_token_url += "&grant_type=authorization_code";
access_token_url += "&redirect_uri=http://localhost:8080/salesgoal/googleOuth2Success";
try {
response = restTemplate.exchange(access_token_url, HttpMethod.POST, request, String.class);
}
catch(Exception e){
e.printStackTrace();
Please let me know what i am doing wrong.
Thanks
Following google's oauth2 documentation
Exchange code for access token and ID token
The response includes a code parameter, a one-time authorization code that your server can exchange for an access token and ID token. Your server makes this exchange by sending an HTTPS POST request. The POST request is sent to the token endpoint, which you should retrieve from the Discovery document using the token_endpoint metadata value. The following discussion assumes the endpoint is https://oauth2.googleapis.com/token. The request must include the following parameters in the POST body:
Follwing their documentation there could be validations on the url parameters (which yield the 400 Bad Request error code)
Please check the following:
The redirect_uri is URL_encoded (by using UrlEncoder)
Url parameters don't contain spaces ( checkclient_id and client_secret )
Later Edit:
Also try following oauth2 specification by using 'Content-Type', 'application/x-www-form-urlencoded' headers on the /token request

Http 400 using resttemplate postforobject

Below is the code which gives 400 bad request, tried various options with this but always ends up with 400 bad request, however the same works using OkHttp client
HttpHeaders hh = new HttpHeaders();
RestTemplate rt = new RestTemplate();
String reqBody = new ObjectMapper.writeValueAsString(“test msg”);
headers.set(“Accept”, “text/plain”);
headers.set(“content-type”,”application/json”);
headers.set(“authorization”, “Basic xxxxx”);
headers.set(“ibm-mq-rest-csrf-token”,”blank”);
HttpEntity<String> request = new HttpEntity<>(reqBody.toString());
ResponseEntity<Object> result = rt.postForObject(url, request, Object.class);
Below code works using okhttp
Your content does not appear to be JSON, in both cases it appears to be plain text. Therefore the header
Content-Type: text/plain
should be used rather than
Content-Type: application/json
I am unsure why this works in your OKHTTP example, unless perhaps the media type you use to build your post body somehow over-rides your Content-Type header?

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

Resources