简体   繁体   English

无法使用RestTemplate使用Rest API

[英]Unable to consume a rest api using resttemplate

I have this api i am trying to consume and this is the link https://www.live-rates.com/api/price?key=123456&rate=EUR_USD 我有我要使用的这个api,这是链接https://www.live-rates.com/api/price?key=123456&rate=EUR_USD

I have tried this in my controller 我已经在控制器中尝试过

@ResponseBody
    @RequestMapping(value = { "/start" }, method = RequestMethod.GET)
    public String start() { 
RestTemplate restTemplate = new RestTemplate();

        String quote = restTemplate.getForObject("https://www.live-rates.com/api/price?key=123456&rate=EUR_USD", String.class);
        return quote.toString();
    }

and this in my scheduling program 这在我的计划程序中

package com.boilerplate.components;


import java.util.Date;
import org.slf4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Async;

import com.boilerplate.services.MessageListenerService;
import java.util.Random;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

@Repository
@Transactional
@Configuration
@EnableAsync
@EnableScheduling
public class Scheduler {
//Database read and update and delete
    @Autowired
    private RabbitTemplate rabbitTemplate;

    private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(MessageListenerService.class);

    @Autowired 
    private SessionFactory sessionFactory;

    @Async
    @Scheduled(cron="*/60 * * * * *")
    public void doSomething(){

        RestTemplate restTemplate = new RestTemplate();

        String quote = restTemplate.getForObject("https://www.live-rates.com/api/price?key=123456&rate=EUR_USD", String.class);
        LOGGER.info(quote.toString());

  }


    }

and they all fail to get the exchange rate. 他们都无法获得汇率。

I get this error when using the scheduler 使用调度程序时出现此错误

SEVERE: Unexpected error occurred invoking async method 'public void com.boilerplate.components.Scheduler.doSomething()'. 严重:调用异步方法“ public void com.boilerplate.components.Scheduler.doSomething()”时发生意外错误。 org.springframework.web.client.HttpClientErrorException: 403 Forbidden at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557) at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:264) at com.boilerplate.components.Scheduler.doSomething(Scheduler.java:53) at com.boilerplate.components.Scheduler$$FastClassBySpringCGLIB$$17802b05.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.inter org.springframework.web.client.HttpClientErrorException:403在org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)处被org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)禁止在org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)在org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)在org.springframework.web.client.RestTemplate.getForObject (RestTemplate.java:264)在com.boilerplate.components.Scheduler.doSomething(Scheduler.java:53)在com.boilerplate.components.Scheduler $$ FastClassBySpringCGLIB $$ 17802b05.invoke()在org.springframework.cglib.proxy org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)的.MethodProxy.invoke(MethodProxy.java:204) ),网址为org.springframework.transaction.inter ceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.lang.Thread.run(Thread.java:748) org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)上的ceptor.TransactionInterceptor $ 1.proceedWithInvocation(TransactionInterceptor.java:99)在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(Trans96.96 ),位于org.springframework.aop.interceptor.AsyncExecutionInterceptor $ 1.call(AsyncExecutionInterceptor.java:115)上的org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) (FutureTask.java:266)在java.lang.Thread.run(Thread.java:748)

and this when using the controller 这在使用控制器时

HTTP ERROR 500 HTTP错误500

Problem accessing /boilerplate/start. 访问/ boilerplate / start时出现问题。 Reason: 原因:

 Server Error 

Caused by: 造成原因:

org.springframework.web.util.NestedServletException: Request processing failed; org.springframework.web.util.NestedServletException:请求处理失败; nested exception is org.springframework.web.client.HttpClientErrorException: 403 Forbidden at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:979) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:800) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) 嵌套的异常是org.springframework.web.client.HttpClientErrorException:403在org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java)的org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:979)处禁止:858)在org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)在javax.servlet.http.HttpServlet.service(HttpServlet.java:687) org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:800)的HttpServlet.java:790)org.eclipse.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1669)的HttpServlet.java:790)

I have tried consuming other json apis like https://jsonplaceholder.typicode.com/posts/1 and i can get the json without any problem. 我已经尝试使用其他json API,例如https://jsonplaceholder.typicode.com/posts/1并且我可以毫无问题地获取json。

Why cant i get the exchange rate using the rest template. 为什么我无法使用其余模板获取汇率。

Did you try adding below code. 您是否尝试添加以下代码。 You are trying to invoke with HTTPS. 您正在尝试使用HTTPS进行调用。

CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()) .build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient); RestTemplate restTemplate = new RestTemplate(requestFactory); String quote = restTemplate.getForObject("https://www.live-rates.com/api/price?key=123456&rate=EUR_USD", String.class);

You don't need to use @Async with your @Scheduled annotation. 您不需要将@Async@Scheduled批注一起使用。 The scheduler will run on it's own thread anyways. 无论如何,调度程序将在其自己的线程上运行。 Of course, one or more running scheduler will run sequentially, but that can be change. 当然,一个或多个正在运行的调度程序将按顺序运行,但是可以更改。 For your case though, regarding the documentation, it seems that, you might have to provide your restTemplate via dependency injection. 但是对于您的情况,关于文档,似乎您可能必须通过依赖注入来提供restTemplate。 So, @Autowire could do the trick. 因此,@ @Autowire可以解决问题。 Documentation, section 27.4.2 . 文档,第27.4.2节

Notice that the methods to be scheduled must have void returns and must not expect any arguments. 请注意,要调度的方法必须具有空返回值,并且不能期望任何参数。 If the method needs to interact with other objects from the Application Context, then those would typically have been provided through dependency injection. 如果该方法需要与应用程序上下文中的其他对象进行交互,则通常将通过依赖项注入来提供这些对象。

So, removing the @Async and adding the dependency injection of restTemplate could do the trick. 因此,删除@Async并添加@Async的依赖项注入restTemplate可以解决问题。

In case you need to know how to run multiple schedulers in different threads, you could check this answer . 如果您需要了解如何在不同的线程中运行多个调度程序,可以检查此答案

与原始问题无关,但是如果变量'quote'已经是'String'类型的,为什么需要在其上调用方法'toString()'?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM