Cannot send POST request with RestTemplate - java

I have 2 services:
Service Web on http://localhost:8080 and Service Engine on http://localhost:8081
Service Web sends a POST request to Service Engine through this code :
String checkWinUrl = customProperties.getEngineUrl() + "/checkWin";
RestTemplate restTemplate = new RestTemplate();
HttpEntity<GameDto> request = new HttpEntity<>(new GameDto(game));
try {
ResponseEntity<CheckWinResult> response = restTemplate.exchange(
checkWinUrl,
HttpMethod.POST,
request,
CheckWinResult.class);
CheckWinResult checkWinResult = response.getBody();
if (checkWinResult != null && checkWinResult.isWin()) {
Set<Move> result = new HashSet<>();
for (MoveDto move : checkWinResult.getWinMoves()) {
result.add(Move.builder().color(GomokuColor.GREEN).columnIndex(move.getColumnIndex()).rowIndex(move.getRowIndex()).build());
}
return result;
}
} catch (RestClientException e) {
log.error("Error while computing checkWin : " + e.getMessage());
}
RestController
#PostMapping("/checkWin")
public CheckWinResult checkWin(#RequestBody GameDto game) {
return engineService.checkWin(game);
}
and it works fine, Engine Service receives the request properly.
But when Engine Service sends a request to Web Service :
String webAppUrl = customProperties.getWebAppUrl() + "/engineMessage";
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> request = new HttpEntity<>(message.toString());
restTemplate.exchange(webAppUrl, HttpMethod.POST, request, Void.class);
RestController
#PostMapping("/engineMessage")
public void engineMessage(#RequestBody String engineMessage) {
JSONObject jsonMessage = new JSONObject(engineMessage);
WebSocketMessage webSocketMessage = new WebSocketMessage();
webSocketMessage.setType(MessageType.valueOf(jsonMessage.getString("type")));
webSocketMessage.setContent(jsonMessage.getString("content"));
webSocketController.sendMessage(webSocketMessage);
}
Web Service just never receives the request.
Any ideas?
Thank you.

Related

How to use CloudHealth API (provided by vmware) for fetching reports of client or tenant in spring boot application?

I want to implement CloudHealth API in my Spring Boot application. I want to fetch report of particular client. I have a dropdown where logged in user select reports and that report will be directly fetched from CloudHealth platform. I want to do that thing in my application. I want to generate JSON response of custom report. I followed API documentation available at https://apidocs.cloudhealthtech.com/#reporting_data-for-custom-report
but I am getting 404 Not Found: "{"error":"Record with id not found."}"
This is the code written in my service class:
public String getCustomReportData(String reportId) {
ResponseEntity<String> responseEntity = null;
String response = null;
try {
final String uri = "https://chapi.cloudhealthtech.com/olap_reports/custom/"+reportId;
RestTemplate restTemplate = new RestTemplate();
HttpHeaders header = new HttpHeaders();
header.set(HttpHeaders.AUTHORIZATION, "Bearer my-api-key");
header.set(HttpHeaders.ACCEPT,"application/json");
HttpEntity<String> requestEntity = new HttpEntity<String>("body",header);
responseEntity = restTemplate.exchange(uri, HttpMethod.GET, requestEntity, String.class);
response = responseEntity.getBody();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return response;
}
This is main endpoint in my restcontoller:
#RequestMapping(value = {"/custom_report/{report_id}"}, method = {RequestMethod.GET, RequestMethod.POST}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<Object> getCustomCloudHealthReports(HttpServletRequest request,#PathVariable("report_id") String reportId){
try {
String response = standardReportService.getCustomReportData(reportId);
return new ResponseEntity<Object>(response, HttpStatus.OK);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
return new ResponseEntity<Object>("Please try again later", HttpStatus.INTERNAL_SERVER_ERROR);
}
}

How to capture error responses from Rest Template in spring boot?

I've 2 springboot REST APIs REST-A & REST-B. REST-B is interacting with mongodb for CRUD operations. And REST-A is calling REST-B endpoints for different reasons.
Controller in REST-B (Customer API)
public class CustomerController {
#Autowired
private CustomerRepository customerRepository;
#GetMapping(value = "/customers/{id}")
public ResponseEntity<Customer> getCustomerByExternalReferenceId(#PathVariable(value = "id") String id)
throws ResourceNotFoundException {
System.out.println("Customer id received :: " + id);
Customer customer = customerRepository.findByExternalCustomerReferenceId(id)
.orElseThrow(() -> new ResourceNotFoundException("Customer not found for this id :: " + id));
return ResponseEntity.ok().body(customer);
}
}
This endpoint works fine if I call from postman for both if customer found in DB and if customer not found in DB.
Now, if I try to call the same endpoint from REST-A and if customer found in DB I can get the response.
String url = "http://localhost:8086/customer-api/customers/{id}";
String extCustRefId =
setupRequest.getPayload().getCustomer().getCustomerReferenceId();
// URI (URL) parameters
Map<String, String> urlParams = new HashMap<>();
urlParams.put("id", extCustRefId); // here I tried with id that exists in DB and getting 200 ok response
HttpHeaders headers = new HttpHeaders();
headers.set("X-GP-Request-Id", "abc-xyz-123");
headers.set("Content-Type", "application/json");
headers.set("Accept", "application/json");
headers.set("Content-Length", "65");
String searchurl = UriComponentsBuilder.fromUriString(url).buildAndExpand(urlParams).toString();
System.out.println(searchurl);
HttpEntity request = new HttpEntity(headers);
RestTemplate restTemplate = new RestTemplate();
try {
ResponseEntity<String> response = restTemplate.exchange(
searchurl,
HttpMethod.GET,
request,
String.class
);
} catch (Exception e) {
e.printStackTrace();
}
But if there's no customer found from REST-B (Customer API) then I'm getting
http://localhost:8086/customer-api/customers/customer-528f2331-d0c8-46f6-88c2-7445ee6f4821
Customer id received :: customer-528f2331-d0c8-46f6-88c2-7445ee6f4821
org.springframework.web.client.HttpClientErrorException: 404 null
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:78)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
How do I call rest endpoint from one springboot application to another and handle response properly?
You can get the response body from HttpClientErrorException as follows:
try {
ResponseEntity<String> response = restTemplate.exchange(
searchurl,
HttpMethod.GET,
request,
String.class
);
} catch (HttpClientErrorException e) {
String errorResponseBody = e.getResponseBodyAsString();
e.printStackTrace();
}
You can then use Jackson ObjectMapper to map the String to a Java object.

Response status code showing 200 for gateway error (504)

I have a REST endpoint which call another API which take a while to process and returning 504 error when I verify through Rest client (Insomnia). But in my service I see this transaction as success 200 not 504.
Below is how my code snippet:
public ResponseEntity<Customer> processResponse(Customer customer, String restUri) {
ResponseEntity<Customer> response;
String customerJson = null;
try {
RestTemplate restTemplate = restTemplateBuilder.basicAuthorization(userName, password).build();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Customer> entity = new HttpEntity<>(customer, headers);
CustomerJson = jacksonUtil.toJSON(customer);
response = restTemplate.exchange(restUri, HttpMethod.PUT, entity, Customer.class);
if (response.getStatusCode().is2xxSuccessful()) {
logger.info("Return success from the server");
} else {
logger.error("Error while getting the response from the server");
}
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
return response;
}
What am I missing here? Why its not executing the else block?
Thanks in advance.
Your method seems to be returning null response in case of error. Can you check if you have done any handling in caller and passing 200 from controller layer itself.

restTemplate postForEntity sometimes leads into 400 Error

In my Android app I try to make a POST via restTemplate.postForEntity() but the first time I try to post the data I get a 400 error. After my timetrigger sync-method try to post the data again it works and I get 200. I don't think it's a backend problem, because I did a couple requests via Swagger and Postman on the same interface and all of them worked without a problem.
This is the error I get:
POST request for "<url>" resulted in 400 (); invoking error handler
org.springframework.web.client.HttpClientErrorException: 400
This is what I see at the postForEntity() when I'm debugging:
'java.lang.NullPointerException' Cannot evaluate org.springframework.http.ResponseEntity.toString()
This is the code:
public ResponseEntity<ArrayList> postServiceData(List<BasicService> attributes) {
HttpStatus status = null;
ResponseEntity<ArrayList> chargerServiceResponse = new ResponseEntity<ArrayList>(status);
try {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpEntity<?> entity = RestServiceUtils.getHttpEntity(attributes, context);
chargerServiceResponse = restTemplate.postForEntity(url, entity, ArrayList.class);
SynchronisationStorage synchronisationStorage = new SynchronisationStorage(context);
synchronisationStorage.updateLastSynchronisationDate();
loggingStorageDbHelper.logSuccess(R.string.logging_save_send_charger_service_to_backend, 1000);
} catch (HttpClientErrorException e) {
/* do stuff*/
}
}
To set the body and token:
#NonNull
public static HttpEntity<?> getHttpEntity(List attributes, Context context) {
HttpHeaders headers = new HttpHeaders();
try {
headers.set(ServiceAppConstants.HEADER_ACCEPT, ServiceAppConstants.MEDIATYPE_JSON);
UserStorage userStorage = new UserStorage(context);
String token = userStorage.getJsonWebToken();
headers.set(ServiceAppConstants.HEADER_SECURITY_TOKEN, token);
}catch (Exception ex){
Log.e(RestServiceUtils.class.getName(), "Exception ocurred while trying to set token to header", ex);
}
return new HttpEntity<Object>(attributes, headers);
}

A method in java application .Which method should return data from Rest Api

I have an application in JavaFX and spring boot. Another web application in spring boot. From web application, I can access Fx application through rest API. But now I want to call a method in java Fx application. Which method return data as String from the web application.How can I do this?
public String getCustomerData(){
/* RestUrl Of web application */
String url="http://192.168.012.106:8080/restrole/customer/get/1?access_token=e91ad118-141a6026b954";
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("HeaderName", "value");
headers.add("Content-Type", "application/json");
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpEntity<Customers> request = new HttpEntity<>(Customers, headers);
restTemplate.postForObject(url, request, Customers.class);
/* here I want to catch the JSON data and return it.*/
return null;
}
protected ResponseEntity<AllCustomerTypeMessage> getCustomerData(String token) {
try {
String url = "http://192.168.012.106:8080/restrole/customer/get?access_token=" + token;
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<AllCustomerTypeMessage> allCustomerType = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<Object>(headers), AllCustomerTypeMessage.class);
return allCustomerType;
} catch (Exception e) {
// Log.e(TAG,e.getMessage(),e);
}
return null;
}

Categories