我正在尝试使用这个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.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) 在org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641) 在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.MethodProxy.invoke(MethodProxy.java:204) 在org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 在org.springframework.transaction.interceptor.TransactionInterceptor $ 1.proceedWithInvocation(TransactionInterceptor.java:99) 在org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) 在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.aop.interceptor.AsyncExecutionInterceptor $ 1.call(AsyncExecutionInterceptor.java:115) 在java.util.concurrent.FutureTask.run(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.processRequest(FrameworkServlet.java:979) 在 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:687)处 org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:790)处 org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:800) 在 org.eclipse.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1669)
我尝试使用其他https://jsonplaceholder.typicode.com/posts/1
之类的json api,我可以毫无问题地获取json。
为什么我无法使用其余模板获取汇率。
答案 0 :(得分:4)
您尝试添加以下代码吗?您正在尝试使用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);
答案 1 :(得分:1)
您不需要在@Async
注释中使用@Scheduled
。无论如何,调度程序将在其自己的线程上运行。当然,一个或多个正在运行的调度程序将按顺序运行,但是可以更改。但是对于您的情况,关于文档,似乎您可能必须通过依赖注入来提供restTemplate。因此,@Autowire
可以解决问题。 Documentation, section 27.4.2。
请注意,要调度的方法必须具有无效的返回值,并且 不能期望任何参数。如果方法需要与之交互 应用程序上下文中的其他对象,那么通常 是通过依赖项注入提供的。
因此,删除@Async
并添加restTemplate
的依赖项注入就可以解决问题。
如果您需要了解如何在不同的线程中运行多个调度程序,可以选中此answer。
答案 2 :(得分:0)
与原始问题无关,但是如果变量'quote'已经是'String'类型的,为什么需要在其上调用方法'toString()'?