Spring @FeignClient,OAuth2和@Scheduled无效

时间:2017-06-01 02:22:48

标签: spring spring-security-oauth2 spring-scheduled spring-cloud-feign

添加了OAuth2FeignRequestInterceptor来处理OAuth2 @FeignClient请求,我现在看到以下异常:

*org.springframework.beans.factory.BeanCreationException: Error 
creating bean with name 'scopedTarget.oauth2ClientContext': Scope 
'session' is not active for the current thread; consider defining a 
scoped proxy for this bean if you intend to refer to it from a         
singleton; nested exception is java.lang.IllegalStateException: No 
thread-bound request found: Are you referring to request attributes 
outside of an actual web request, or processing a request outside of 
the originally receiving thread? If you are actually operating within a 
web request and still receive this message, your code is probably 
running outside of DispatcherServlet/DispatcherPortlet: In this case, 
use RequestContextListener or RequestContextFilter to expose the 
current request.
    at 
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355)

    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:187)
    at com.sun.proxy.$Proxy157.getAccessToken(Unknown Source)
    at org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor.getToken(OAuth2FeignRequestInterceptor.java:124)
    at org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor.extract(OAuth2FeignRequestInterceptor.java:112)
    at org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor.apply(OAuth2FeignRequestInterceptor.java:100)
    at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:154)
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:88)
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
    at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
    at com.sun.proxy.$Proxy173.getNewEmployees(Unknown Source)
    at com.manulife.gsd.scheduling.NewEmployeeCreateUpdateScheduler.addNewEmployees(NewEmployeeCreateUpdateScheduler.java:34)
    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.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
    at org.springframework.web.context.request.SessionScope.get(SessionScope.java:91)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340)
    ... 27 common frames omitted*

没有OAuth2一切正常,将OAuth2添加到服务器并且正如预期的那样访问方法受到限制。

任何帮助都将受到赞赏 - 将使用RestTemplate而不是@FeignClient,但我不确定我的@Scheduled工作是否会遇到同样的问题?

@FeignClient

*@FeignClient(name = "newemployee-service", configuration = 
FeignClientConfiguration.class, url = "${newemployee-
service.ribbon.listOfServers}")
public interface NewEmployeeServiceClient { 

@RequestMapping(method = RequestMethod.GET, value = 
"/newemployee/pilot", produces = "application/json")
List <Employee> getNewEmployees();
//String getNewEmployees();
}*

FeignClientConfiguration

*@Configuration    
public class FeignClientConfiguration {
@Value("${newemployee.security.oauth2.client.access-token-uri}")
private String tokenUrl;
@Value("${newemployee.security.oauth2.client.client-id}")
private String clientId;
@Value("${newemployee.security.oauth2.client.client-secret}")
private String clientSecret;
// See https://github.com/spring-cloud/spring-cloud-netflix/issues/675
@Bean
public RequestInterceptor 
oauth2FeignRequestInterceptor(OAuth2ClientContext oauth2ClientContext){
    return new OAuth2FeignRequestInterceptor(oauth2ClientContext, 
    resource());
}
@Bean
protected OAuth2ProtectedResourceDetails resource() {
    AuthorizationCodeResourceDetails resource = new 
AuthorizationCodeResourceDetails();
    resource.setAccessTokenUri(tokenUrl);
    resource.setClientId(clientId);       
    resource.setClientSecret(clientSecret);
    return resource;
}*

NewEmployeeCreateUpdateScheduler

@Component
public class NewEmployeeCreateUpdateScheduler {

    @Inject
    private EmployeeRepository employeeRepository;

    @Inject
    private NewEmployeeServiceClient newEmployeeServiceClient;

    private final Logger log = LoggerFactory.getLogger(NewEmployeeCreateUpdateScheduler.class);

    @Scheduled(cron = "*/30 * * * * *")
    //@Scheduled(cron = "0 0 */2 * * *")
    public void addNewEmployees() {

        log.info("------- GET NEW EMPLOYEES SCHEDULER --------------");

        Employee employee = null;
        List<Employee> newEmployees = newEmployeeServiceClient.getNewEmployees();

        if(newEmployees == null) {
            log.info("------- NO NEW EMPLOYEES --------------");
        } else {
            log.info("------- AS EXPECTED WE HAVE NEW EMPLOYEES --------------"); 
            for (Employee newEmployee : newEmployees) {
                log.debug("----- Create/Update New Employee: " + newEmployee + "------");
                // check if employee already exists - need to call method to see if employee exists
                log.debug("----- Check if employeeId already exists with employee id: " + newEmployee.getEmployeeId() + "-----");
                employee = employeeRepository.findByEmployeeId(newEmployee.getEmployeeId());
                log.debug("----- Employee lookup by employee id: " + employee + " -----");
                if (employee == null) {
                    Employee result = employeeRepository.save(newEmployee);
                    log.debug("----- Result of Created New Employee: " + result + "-----");
                } else {
                    newEmployee.setId(employee.getId());
                    Employee result = employeeRepository.save(newEmployee);
                    log.debug("----- Result of Updated Existing Employee Data: " + result + "-----");
                }

            }   

        }

感谢您的帮助!

尝试使用RestTemplate时出现同样的错误......

ResponseEntity<List<Employee>> employeeResponse =
        restTemplate.exchange(url,
             HttpMethod.GET, null, new 
             ParameterizedTypeReference<List<Employee>>() {
               });

0 个答案:

没有答案