Microservice Client using SpringBoot's RestTemplate class - java

I am new to Client side of microservice architecture. I am building a rest based client to submit mine form data using above piece of code.
public ResponseEntity<?> saveCustomerInfo(RegisterCustomer customerModel) {
RestTemplate restTemp = new RestTemplate();
String url= "http://localhost:8081/applicationDemo/saveCustInfo";
HttpEntity http = new HttpEntity(customerModel);
System.out.println(customerModel);
ResponseEntity resp =
restTemp.postForEntity(url,http,ResponseEntity.class);
System.out.println(resp.getBody());
return null;
When i test above code using POSTMAN , it show exception as given below :
org.springframework.web.client.HttpClientErrorException: 415 null
I am not able to get what is gone wrong because when i hit micro services without client, it save the data.But when i use this Rest Template based method, it shows above exception.

Related

Getting a 400 Bad Request when Angular HttpClient posts a Set<> to a SpringBoot endpoint

I am exposing an endpoint that accepts a Set<> as a #RequestBody this way :
public #ResponseBody ResponseEntity<Response> addTeamOwner(#RequestParam("teamName") String teamName, #RequestBody Set<String> emails, HttpServletRequest request){...}
And my Angular frontend is calling this endpoint like this :
let params = new HttpParams().set('teamName', teamName);
let url = `${UrlManager.TEAMS}/addOwners?${params.toString()}`;
this.httpClient.post<any>(url, emails);
For some reason I'm getting 400 Bad Request : HttpErrorResponse {headers: HttpHeaders, status: 400, statusText: 'Bad Request', url: 'http://localhost:4200/api/teams/addOwners?teamName=DEMO_TEAM', ok: false, …}
It seems that the Set that Angular is sending is not accepted by the backend because when I change to an Array everything works fine !
FYI, my API is SpringBoot and my frontend is Angular.
Actually it is not possible to serialize data sent within Set because the data are not stored as properties.
The solution was to convert the set to an array this way :
this.httpClient.post<any>(url, [...emails]);
and the backend is able to deserialize it as a Set correctly.

Calling multiple external APIs in Spring Boot

I am working on a project but it requires me to call multiple external APIs. I basically have to call an API to get a player id by giving a name. Then use that player id to get a list of match ids. Then make calls for each match id to get details on each match. its alot and doesnt seem optimal but its the only way to do it. I was going to use rest template to make a call to the following
https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/HDzjdaStxhHcceGGd8qJcc4Vw45FOlOQ1PNXKQ0h9_iqfwHP3oI0spl1bLUOw_7_J49vzaIKylv5Vg/ids?start=0&count=20
I have to pass in headers as well such as
riot token : token
"Origin": "https://developer.riotgames.com"
I was wondering how I can do this in Java Spring boot. I saw RestTemplate would be used but I couldnt figure out how to include the headers. Any guidance would be appreciated.
You can call RestTemplate.exchange() using either the method signature with RequestEntity or with HttpEntity.
// Using RequestEntity
RequestEntity<?> request= RequestEntity.get(url).header(headerName, headerValue).build();
ResponseEntity<String> response = restTemplate.exchange(request, String.class);
// Using HttpEntity
HttpHeaders headers = new HttpHeaders();
headers.set(headerName, headerValue);
HttpEntity httpEntity = new HttpEntity(/* this is nullable */ requestBody, headers);
ResponseEntity,String> response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
Would also recommend reading through the following:
https://howtodoinjava.com/spring-boot2/resttemplate/spring-restful-client-resttemplate-example/
https://www.baeldung.com/rest-template
How to set an "Accept:" header on Spring RestTemplate request?

Spring boot rest template - HttpMessageConverter cannot convert objects

hello everyone I have a problem that I do not understand why this is happening. I am working with spring boot and deploying with Kubernetes. after a while, the restTemplate stops working and I do not know what can be the cause. this is how I am creating the restTemplate class
#Bean
public RestTemplate vanillaRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new RestTemplateErrorHandler());
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
return restTemplate;
}
after a while some of my APIs that is using restTemplate returns an error like this:
{
"status": 500,
"body": "{ message: Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.List] and content type [application/json;charset=UTF-8] , cause: null }",
}
this is only an example. resttemplate will have a problem with many classes such as Map, String, etc when this happens. and this is how I am sending the request:
ResponseEntity<List> adsRes = restTemplate.getForEntity(url, List.class);
the weird part is when I restart the app on the server everything starts working again and the APIs have no problem at all. even the ones that returned an error.
I have read this question but, as you can see I have not set any interceptor or anything like that to resttemplate
thanks in advance
Try replace the way how you are calling to the endpoint by the following code
ResponseEntity<YourObject[]> response = restTemplate.getForEntity("urlService",
YourObject[].class);
YourObject[] yourObjects= response.getBody();
List<YourObject> list = Arrays.asList(yourObjects);

SessionId lost when I make a request between backend of microservices

I am trying to make request between microservices in order to retrieve a list of users with the same roles. For this, first I make a request between FrontEnd and Backend inside the microservice 1. Following, I call an endpoint in the microservice 2 from Microservice 1 backend, but the session Id is lost in it, and I can retrieve the context.
I am using spring security and Redis for the session Control.
Manually, I retrieve the session Id from the microservice 1 and I add it as an attribute of the header of the second call, to the microservice 2. But it does not work.
String sessionID= RequestContextHolder.currentRequestAttributes().getSessionId();
RestTemplate rest = new RestTemplate();
HttpHeaders headers= new HttpHeaders();
headers.set("Session",sessionID);
HttpEntity<ResponseData> entity = new HttpEntity<ResponseData>(headers);
ResponseEntity<ResponseData> responseEntity =rest.exchange(targetApi, HttpMethod.GET, entity,ResponseData.class);
Finally, I resolved the problem adding an interceptor as a component:
#Component
public class SpringSessionClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
#Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
request.getHeaders().add("Cookie", "SESSION=" + sessionId);
return execution.execute(request, body);
}
}
And I created a #Bean to configure the rest template:
#Bean
public RestTemplate restTemplate(){
RestTemplate rest = new RestTemplate();
ClientHttpRequestInterceptor interceptor= new SpringSessionClientHttpRequestInterceptor();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
interceptors.add(interceptor);
rest.setInterceptors(interceptors);
return rest;
}
I don't know the exact answer to your question but in terms of your design I'd question if you really want to make your microservice1 depending on microsevice2. A microservice should be autonomous in the way it works and being able to be deployed on it's own (in theory anyway!). May be you could have an orchestrating microservice that receives your session information and then calls the 2 other microservices to pass that information on via 'standard' attributes.
headers.set("Session",sessionID);
I assume that the problem is that you are using the wrong identifier. As far as I know, it is JSESSIONID by default.
Another problem that I can see here is that JSESSIONID expected to be in cookies. Try to put it in cookies when sending a request to your 'microservice2'.

How to get the HTTP status of an API in spring boot when we hit it internally using Rest template

I want to get the object as well as the HTTP response of one api into another in Spring code. For that I am using a rest template and I am getting the desired Object from it successfully.
But I want to fetch HTTP response also for the respective api.
What should I do to get this?
RestTemplate restTemplate = new RestTemplate();
Quote quote = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
System.out.println("quote "+quote);
System.out.println(quote.getType());
log.info(quote.toString());
getForObject method of RestTemplate only gets the result. If you're interest in the status code you should invode exchange which returns a ResponseEntity which has a getStatusCode method.
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Quote> response= restTemplate.exchange ("http://gturnquist-quoters.cfapps.io/api/random", HttpMethod.GET, null, Quote.class);
Quote quote = response..getBody();
System.out.println("status "+response..getStatusCode());
System.out.println("quote "+quote);
System.out.println(quote.getType());

Categories

Resources