I'm trying to create a GET request to retrieve commercial flights from latam. But I only get the answer through insomnia/postman...
I'm making the request through RestTemplate in Java, as shown below:
public class LatamRequest {
public void consumerAPILatam(){
RestTemplate template = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
//h.ttps://www.latamairlines.com/bff/air-offers/offers/search
UriComponents uri = UriComponentsBuilder.newInstance()
.scheme("https")
.host("www.latamairlines.com")
.path("bff/air-offers/offers/search")
.queryParam("sort","RECOMMENDED")
.queryParam("cabinType","Economy")
.queryParam("origin","GRU")
.queryParam("destination","BSB")
.queryParam("inFlightDate","null")
.queryParam("inFrom","null")
.queryParam("inOfferId","null")
.queryParam("outFlightDate","null")
.queryParam("outFrom","2022-11-15T15%3A00%3A00.000Z")
.queryParam("outOfferId","null")
.queryParam("adult","1")
.queryParam("child","0")
.queryParam("infant","0")
.queryParam("redemption","true")
.build();
headers.set("User-Agent", "test");
headers.set("Accept", "*/*");
headers.set("Content-Type", "application/json");
headers.set("X-latam-App-Session-Id", "84196897-1687-4d8c-8e63-083091ac204f");
headers.set("X-latam-Action-Name", "search-result.flightselection.offers-search");
headers.set("X-latam-Application-Name", "web-air-offers");
headers.set("X-latam-Client-Name", "web-air-offers");
headers.set("X-latam-Track-Id", "3a4ae189-e218-4606-bd9e-8b17efc93463");
headers.set("X-latam-Request-Id", "ff44ef24-e6d0-4cb0-984c-df1db18cee19");
headers.set("X-latam-Application-Country", "BR");
headers.set("X-latam-Application-Oc", "br");
headers.set("X-latam-Application-Lang", "pt");
HttpEntity<String> httpEntity = new HttpEntity<>(headers);
ResponseEntity<String> response = template.exchange(uri.toUriString(), HttpMethod.GET, httpEntity, String.class); //todo: No response, no error...
System.out.println(response);
}
}
I don't get any response or status after executing the above block. OBS: With the same parameters and headers I get status 200 in postman or insomnia.
I've tried several ways, but I can't get a response. Does anyone have any ideas for a more effective debug?
The reason that you don't get any response and no exception is because the server side gets your request and keeps holding it and doesn't respond. So you are still in a waiting mode. I ran your request from java code using different http client but used exact your params and I noticed that response never returns. I waited for over 10 minutes and I saw that the program was still running. So I modified the code and added connection timeout for 5 sec and read timeout for 30 seconds. When I ran it it I got read timeout exception after 30 seconds. So the code manages to connect to server side, but server side just doesn't respond. So you are in endless wait. So, I don't know why it works from postman. May be some headers values issues.
Related
What is the difference with UniRest and Spring RestTemplate which is giving back a 400 Bad Request with apparently the same header and body sent ?
I try to reach the HubSpot API to create a BlogPost, but using RestTemplate I have a 400 Bad Request error, and using UniRest works alright (returns an OK response). However, I do not want to include a library just to make one REST call: I'd rather stick to RestTemplate.
The request data I need to send
HttpMethod: POST
URL: https://api.hubapi.com/content/api/v2/blog-posts?hapikey=*****************
Header: Content-Type: application/json
Body: (represented by a class instance as blogpostSendPost further down)
{
"name": "My first API blog post!",
"content_group_id": 351076997
}
Using RestTemplate
Setting up the request:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<BlogpostSendPost> request = new HttpEntity<>(blogpostSendPost, headers);
log(request.toString());
//LOG PRINT: <BlogpostSendPost(name=My first API blog post!, content_group_id=351076997),[Content-Type:"application/json"]>
OR in JSON
The .json() method converts my object in Json like you can see in the logs
HttpEntity<String> request = new HttpEntity<>(blogpostSendPost.toJson(), headers);
log(request.toString());
//LOG PRINT: <{"name":"My first API blog post!","content_group_id":"351076997"},[Content-Type:"application/json"]>
With .postForObject(): 400 Bad Request
BlogpostResponsePost answer = restTemplate.postForObject(
"https://api.hubapi.com/content/api/v2/blog-posts?hapikey=***********",
request,
BlogpostResponsePost.class);
With .exchange(): 400 Bad Request
BlogpostResponsePost answer = restTemplate.exchange(
"https://api.hubapi.com/content/api/v2/blog-posts?hapikey=**********",
HttpMethod.POST,
request,
BlogpostResponsePost.class);
Using UniRest: OK
HttpResponse<JsonNode> resp = Unirest
.post("https://api.hubapi.com/content/api/v2/blog-posts?hapikey=**********")
.header("Content-Type", "application/json")
.body(blogpostSendPost)
.asJson();
I am using PostMan to call my REST SpringBoot Application which is using theses Services : when I am calling the HubSpot API directly from PostMan it works fine, just like with UniRest lib.
Thanks for your help guys !!
Please refer https://community.hubspot.com/t5/APIs-Integrations/Getting-400-Bad-Request-when-trying-to-add-a-Blog-Post/td-p/306532
Instead of converting request object to json, pass request object directly. It worked for me.
// TRY 1: CONTACTS - RestTemplate - OK - contact is created (API V1)
HttpEntity request1 = new HttpEntity<>(contactSendList, headers);
ContactResponseInformations answer1 = restTemplate
.postForObject(
HubSpotConfiguration.URL_CREATE_CONTACT,
request1,
ContactResponseInformations.class);
log.info(answer1.toString()); // OK
I have implemented a PerformHttpPostRequest function which is supposed to send a post request contains a JSON type body and get a JSON response via Apache HttpClient.
public static String PerformHttpPostRequest(String url, String requestBody) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
StringEntity entity = new StringEntity(requestBody);
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
CloseableHttpResponse response = client.execute(httpPost);
HttpEntity httpEntity = response.getEntity();
InputStream is = httpEntity.getContent();
return (new BufferedReader(new InputStreamReader(is, "UTF-8"))).readLine();
}
The problem is, the code works perfect on developing environment, but when running the war file with a tomcat server but the request is not executed.
I've tried adding several catch blocks such as IOException, Exception and the code doesn't get there.
I've added debug prints which demonstrated that the code stops responding at the client.execute(...) command.
The function is called inside a try block, and after executing the .execute(...) command the code does get to the finally block.
I've already searched for a similar problem and didn't find an answer.
Is it a known issue? Does anyone have any idea of what can cause that? Or how can I fix it?
Hi Talor nice to meet you,
Please try to use HttpURLConnection to solve this issue like so:
Java - sending HTTP parameters via POST method easily
Have a nice day.
el profesor
I have tried with RestTemplate.
RequestObject requestObject = new RequestObject();
requestObject.setKey("abcd");
requestObject.setEndpoint(serviceEndPoint);
RestTemplate restTemplate = new RestTemplate();
HttpEntity<RequestObject> requestBody = new HttpEntity<RequestObject>(
requestObject);
ResponseEntity<RequestObject> result = restTemplate.postForEntity(
serviceEndPoint, requestBody, RequestObject.class);
Its very simple and hassle free, hope it helps
Few things you can try out.
- Try to do ping/curl from that box where you are running tomcat.
- Try to have a test method which make a get request to a server which is always reachable. For ex google.com and print the status. That way you could be able to know that you code is actually working or not in server env.
Hope this helps. :)
If the code doesn't pass beyond client.execute(...) but it does execute the finally block in the calling code, then you can find out what caused the aborted execution by adding this catch block to the try block that contains the finally:
catch(Throwable x) {
x.printStackTrace();
}
Throwable is the superclass for all exception and error classes, so catching a Throwable will catch everything.
I have a rest service and is consumed using Spring's RestTemplate with Apache HttpClient as,
#Autowired
public ClientImpl(#Value("${base-uri}") final String baseUrl,
#Qualifier("restOperations") RestOperations restTemplate) {
serviceUrl = baseUrl;
restTemplate = restTemplate;
}
private List<ResponseDetails> processRequest(CustomRequest request) throws Exception {
ResponseEntity<ResponseDetails[]> responseEntity = restTemplate.exchange(serviceUrl, HttpMethod.POST, entity, ResponseDetails[].class);
if (responseEntity.getStatusCode().value() == 204) {
return Collections.<ResponseDetails>emptyList();
}
ResponseDetails[] response = responseEntity.getBody();
return response != null ? Lists.newArrayList(response) : Collections.<ResponseDetails>emptyList();
}
When the webservice returns 204 response, then the second service call after 204 response, fails with read timeout.
Spring-web : 4.3.5
I cannot figure out the cause. Any help?
EDIT:
From debug logs,
org.apache.http.impl.conn.DefaultHttpResponseParser;Garbage in
response: ÿþ{"id":0}HTTP/1.1 204 Could not find
Response in server logs by httpclient:
<204 No Content,{Cache-Control=[no-cache], Pragma=[no-cache],
Content-Type=[application/json; charset=utf-16], Expires=[-1],
Server=[some], X-AspNet-Version=[someversion], X-Powered-By=[ASP.NET],
Date=[somedate]}>
HTTP 204 is status code for "No Content", but there seems to be garbage content in the response. This can be seen on your logs:
ÿþ{"id":0}
This is the cause of problems you have.
HTTP client is not expecting anything in the body content of 204 response so does not read it, hence response handler does not see that there is any garbage. However since there is garbage which is not yet consumed the connection stays open until it is read -> the next connection, which tries to reuse the connection, gets hit with a read timeout.
There is a separate thread about a similar problem, where the problem is worked around with a custom HTTP request executor. Using such executor, you could call getBody() to obtain the garbage response body and then next request would not have any issues.
Code:
HttpContent content = createLoginContent(username, password);
GenericUrl url = new GenericUrl(serverUrl);
HttpRequest postRequest = httpRequestFactory.buildPostRequest(url, content);
postRequest.setThrowExceptionOnExecuteError(false);
HttpResponse httpResponse = postRequest.execute();
For status code OK (200), httpResponse.parseAsString() returns what I expect (body sent from server).
However, when I get a 401 status code, httpResponse.parseAsString() returns an empty string, even though server sends a 'WRONG_USERNAME_OR_PASSWORD' body.
Can I not read the body when a non-OK status code is given? How can I read the 'WRONG_USERNAME_OR_PASSWORD' message using httpResponse?
Server has been tested using RestClient-Tool to show that it does indeed send a body in its response.
Ok, I changed from using google-httpclient to apache-httpclient and it works much better.
I'm working on an application that uses HttpResponse for network calls.
Occasionally (about 30% of the time) network calls seem to fail with a 502 returning from the server. When checking the server logs, It appears that the server never received the request.
The logic doesn't seem bad, however, and it does work most of the time. I am communicating to the server via JSON.
HttpClient client = new DefaultHttpClient();
HttpPost method = new HttpPost( BASE_URL + endpoint )
...add json entity
method.addHeader( "content-type", "application/json" );
method.addHeader( "accept", "application/json" );
....call below function w client/method
protected HttpResponse invoke( HttpClient client, HttpUriRequest method ) throws ServiceException {
HttpResponse response = null;
try {
response = client.execute( method );
} catch ( //catch statements here ....)
int status = response.getStatusLine().getStatusCode();
//status = 502
}
The interesting thing about this call failing is that it's the exact same call across devices, and the server it's hitting is 20 feet away, although it does happen on a different server located in another state.
I can't see why it works sometimes but not others.
Run wire shark on both sender and receiver . Observe sends and receives. You should be able to see the cause of the problem.
If you are getting a 502 error it suggests an intermediate device ( proxy,web filter,etc ) is blocking or " eating " your HTTP post .
Hate to say it, but this just sounds like an infrastructure issue. Some networking problem between your device, and the server. The code itself looks fine