Reputation: 17
I am building spring boot microservices and using REST template to communicate between microservices (via eureka API Gateway). Oddly, a simple request from one service to another returning a String works but any other request and I get the following error:
26 --- [nio-9010-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException$BadRequest: 400 : [{"timestamp":"2021-08-17T14:15:18.209+00:00","status":400,"error":"Bad Request","path":"/accounts/findbycustomernumber"}]] with root cause
org.springframework.web.client.HttpClientErrorException$BadRequest: 400 : [{"timestamp":"2021-08-17T14:15:18.209+00:00","status":400,"error":"Bad Request","path":"/accounts/findbycustomernumber"}]
at org.springframework.web.cl
I have a CustomerProfile microservice which should fetch an "Account" entity from the BankAccount microservice. In my BankAccountService.controller I have 2 methods (which both work correctly:
@GetMapping("/test")
public String test() {
return "Hello World";
}
@GetMapping("/findbycustomernumber")
public ResponseEntity<List<Account>> findbycustomernumber(@RequestParam String customernumber) {
log.info("Inside AccountController::findByCustomerID()");
System.out.println("Customer number: " + customernumber);
List<Account> findByCustomerNumberAccounts =
accountService.findbycustomernumber (customernumber);
return new ResponseEntity<List<Account>>(
accountService.findbycustomernumber(customernumber),
HttpStatus.OK
);
}
And in my CustomerProfile controller I have 2 methods:
@GetMapping("/test")
public ResponseEntity<String> test() {
return customerProfileService.test();
}
@GetMapping("findbycustomernumber")
public ResponseEntity<Account> findByCustomerNumber(@RequestParam String customernumber) {
log.info("Inside: /CustomerProfileController/findbycustomernumber");
return customerProfileService.findByCustomerNumber(customernumber);
}
and their respective methods in the service package using rest template is:
public ResponseEntity<String> test() {
ResponseEntity<String> response = restTemplate.getForEntity(
"http://BANK-ACCOUNT-SERVICE/accounts/test",
String.class);
return response;
}
public ResponseEntity<Account> findByCustomerNumber(String customernumber) {
log.info("Inside CustomerProfileService::findByCustomerNumber()");
String url = "http://BANK-ACCOUNT-SERVICE/accounts/findbycustomernumber";
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>(customernumber, requestHeaders);
ResponseEntity<Account> response = restTemplate.exchange(url, HttpMethod.GET, request, Account.class);
return response;
}
Using postman, if i send a request to localhost:9191/customerprofile/test (9191 because I am using netflix eureka API gateway), the method works fine. The request journey is client->API-Gateway->CustomerProfileService.controller->CustomerProfileService.service->BankAccouunttService.controller->client.
But the second method, findbycustomernumber, which is implemented the same way returns a 400 error code with failure to find path. Why is one working and the other isn't when everything is implemented the same?
I have somewhat edited the code for privacy so you may notice minor errors that may be irrelevant to this issue. But as one RestTemplate request in customer profile services service class is working and the other isnt, I am sure the issue is with how I am calling the restTemplate methods. I have tried all the methods getForEntity, getForObject and Exchange but I always get the same error.
I have searched for quite sometime. I know there are similar questions online but i have still not got anywhere. Thanks
Upvotes: 0
Views: 7710
Reputation: 17
@MidhunMohan is the accepted answer but i'd also like to point out: Get list of JSON objects with Spring RestTemplate
In my question above, I was accepting ReponseEntity<List<Account>>
when it should be ResponseEntity<Account[]>
.
Upvotes: 0
Reputation: 689
400 bad request is due to the missing query parameter of that API.
try to provide url as below in rest template
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
// Add query parameter
.queryParam("customernumber", customernumber);
HttpEntity<?> request = new HttpEntity<>(requestHeaders);
ResponseEntity<Account> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, request, Account.class);
return response;
Upvotes: 1