繁体   English   中英

无法使用RestTemplate使用Rest API

[英]Unable to consume a rest api using resttemplate

我有我要使用的这个api,这是链接https://www.live-rates.com/api/price?key=123456&rate=EUR_USD

我已经在控制器中尝试过

@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();
    }

这在我的计划程序中

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());

  }


    }

他们都无法获得汇率。

使用调度程序时出现此错误

严重:调用异步方法“ public void com.boilerplate.components.Scheduler.doSomething()”时发生意外错误。 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 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)

这在使用控制器时

HTTP错误500

访问/ boilerplate / start时出现问题。 原因:

 Server Error 

造成原因:

org.springframework.web.util.NestedServletException:请求处理失败; 嵌套的异常是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)

我已经尝试使用其他json API,例如https://jsonplaceholder.typicode.com/posts/1并且我可以毫无问题地获取json。

为什么我无法使用其余模板获取汇率。

您是否尝试添加以下代码。 您正在尝试使用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);

您不需要将@Async@Scheduled批注一起使用。 无论如何,调度程序将在其自己的线程上运行。 当然,一个或多个正在运行的调度程序将按顺序运行,但是可以更改。 但是对于您的情况,关于文档,似乎您可能必须通过依赖注入来提供restTemplate。 因此,@ @Autowire可以解决问题。 文档,第27.4.2节

请注意,要调度的方法必须具有空返回值,并且不能期望任何参数。 如果该方法需要与应用程序上下文中的其他对象进行交互,则通常将通过依赖项注入来提供这些对象。

因此,删除@Async并添加@Async的依赖项注入restTemplate可以解决问题。

如果您需要了解如何在不同的线程中运行多个调度程序,可以检查此答案

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

暂无
暂无

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

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