Home > OS >  How to consume or call another Rest API in Spring Boot application?
How to consume or call another Rest API in Spring Boot application?

Time:11-23

I am trying to call an external Rest API endpoints in my Spring Boot application. I have an API key that I generated before using it in my rest application. Whenever I am trying to hit GET request, showing me missing API Key 403 forbidden error.

org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden: "{"error":"Missing API key"}"
    at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:109)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:168)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:122)
    at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:819)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:777)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
    at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:361)
    at com.rakhi.restapidemo.controller.CloudHealthAccessController.getCloudHealthReports(CloudHealthAccessController.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:670)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:750)

I tried writing this code to get desired output. Unfortunately not able to do so.

@RequestMapping(value = {"/reports"}, method = {RequestMethod.GET, RequestMethod.POST}, produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<Object> getCloudHealthReports(){
        logger.info("Inside get cloud health reporting function..!!!!");
        try {
            String apiKey = "abc-xyz-example-apikey-e215d82537ba";
            final String uri = "https://chapi.cloudhealthtech.com/olap_reports";
            RestTemplate restTemplate = new RestTemplate();
            
            URL url = new URL(uri);
            HttpURLConnection http = (HttpURLConnection)url.openConnection();
            
            http.setRequestProperty("Accept", "application/json");
            http.setRequestProperty(HttpHeaders.AUTHORIZATION, String.format("Bearer %s", apiKey));
            
            ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);
            
            return new ResponseEntity<>(response.getHeaders(), HttpStatus.OK);
            
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
            return new ResponseEntity<>("Error! Please try again later", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

CodePudding user response:

HttpURLConnection c = (HttpURLConnection) new URL("https://chapi.cloudhealthtech.com/olap_reports").openConnection();
c.setRequestProperty("Accept", "application/json");
c.setRequestProperty("Authorization", "Bearer abc-xyz-example-apikey-e215d82537ba");
try {
  System.out.println(c.getResponseCode()   ": "   new String(c.getInputStream().readAllBytes()));
} catch(Exception e) {
  System.out.println(c.getResponseCode()   ": "   new String(c.getErrorStream().readAllBytes()));
}

I am getting:

403: {"error":"Unrecognized API key"}

Which is better than 'missing' API key. Maybe try with this example and change one thing at a time.

Have a look at this: Sending GET request with Authentication headers using restTemplate

You need to pass the request headers in a spring specific way.

CodePudding user response:

Are you sure you are giving the proper header to the rest call ?

One thing is ok, is that your API answer you, so it's working but not well.

You probably should also check logs in your responded API if you could. Could it be for exemple :

ApiClient apiClient = new ApiClient();
apiClient.setBasePath("BASE_URL");
apiClient.setApiKeyPrefix("App");
apiClient.setApiKey("API_KEY");
return apiClient;
  • Related