Исключение функции Spring Async при сохранении данных в сеансе - PullRequest
0 голосов
/ 07 марта 2019

У меня проблема с задачей @Async с HttpSession. Я хочу сохранить данные в сеансе в асинхронном методе. Что происходит, ответ возвращается правильно, но я получаю ошибку при сохранении данных в сеансе. Пожалуйста, помогите.

Файл моего контроллера:

@RequestScope
@Controller
public class SomeController {

    @Autowired
    private ISomeService iSomeService;

    @ResponseBody
    @GetMapping("/some-func")
    public String someFunc() {
        iSomeService.myAsyncFunction("hello");
        return "ok";
    }
}

Файл моей службы:

@RequestScope
@Service
public class SomeServiceImpl implements ISomeService {

    @Autowired
    private HttpSession session;

    @Async("threadPoolTaskExecutor")
    @Override
    public void myAsyncFunction(String s) {

        session.setAttribute("key", s);
    }
}

Мой файл конфигурации:

@EnableAsync
@Configuration
public class ThreadConfig {

    @Bean(name = "threadPoolTaskExecutor")
    public Executor threadPoolTaskExecutor() {
        return new ThreadPoolTaskExecutor();
    }
}

My Stacktrace:

2019-03-07 17:23:16.065 ERROR 29179 --- [lTaskExecutor-1] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected error occurred invoking async method: public void com.example.demo.SomeServiceImpl.myAsyncFunction(java.lang.String)

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) ~[spring-web-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:309) ~[spring-web-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at org.springframework.web.context.support.WebApplicationContextUtils.access$400(WebApplicationContextUtils.java:64) ~[spring-web-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at org.springframework.web.context.support.WebApplicationContextUtils$SessionObjectFactory.getObject(WebApplicationContextUtils.java:366) ~[spring-web-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at org.springframework.web.context.support.WebApplicationContextUtils$SessionObjectFactory.getObject(WebApplicationContextUtils.java:361) ~[spring-web-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:307) ~[spring-beans-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at com.sun.proxy.$Proxy93.setAttribute(Unknown Source) ~[na:na]
    at com.example.demo.SomeServiceImpl.myAsyncFunction(SomeServiceImpl.java:21) ~[classes/:na]
    at com.example.demo.SomeServiceImpl$$FastClassBySpringCGLIB$$9dbf1607.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736) ~[spring-aop-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115) ~[spring-aop-4.3.22.RELEASE.jar:4.3.22.RELEASE]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_191]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

На моей голове, если у нас есть @Async аннотации, то я думаю, что тип возвращаемого значения должен быть типа CompletableFuture, как обещание в javascript.
Таким образом, изменение типа возвращаемого значения для метода обслуживания с void на CompletableFuture<Void> решает проблему.

Итак, я изменил код, как показано ниже:

@Async("threadPoolTaskExecutor")
@Override
public CompletableFuture<Void> myAsyncFunction(String s) {

    session.setAttribute("key", s);
    return new CompletableFuture<Void>();
}

// Получить объект сеанса в Async // Это неверный код, но проверить пригодность

Итак, я получаю объект сеанса из HttpRequest и передаю его в службу. Вы добавляете параметры в службу и проверяете эти параметры в контроллере.
Не подключайте объект сеанса автоматически к сервису или контроллеру.

@RequestScope
@Controller
public class SomeController {

@Autowired
private SomeServiceImpl iSomeService;

@ResponseBody
@GetMapping("/some-func")
public String someFunc(HttpServletRequest request) throws ExecutionException, InterruptedException {
    HttpSession session = request.getSession();
    CompletableFuture<HttpSession> completableFuture= iSomeService.myAsyncFunction(session, "hello");
    HttpSession session1=completableFuture.get();
    System.out.println(session1.getAttribute("key"));
    return "ok";
}
}

@RequestScope
@Service
public class SomeServiceImpl {

@Async("threadPoolTaskExecutor")
public CompletableFuture<HttpSession> myAsyncFunction(HttpSession session, String s) {
    session.setAttribute("key", s);
    return CompletableFuture.completedFuture(session);
}
}
1 голос
/ 07 марта 2019

Согласно Async Java док.void является допустимым типом возврата.

С точки зрения сигнатур целевого метода поддерживаются любые типы параметров.Однако тип возвращаемого значения ограничен либо {@code void}, либо {@link java.util.concurrent.Future}.В последнем случае вы можете объявить более конкретные типы {@link org.springframework.util.concurrent.ListenableFuture} или {@link java.util.concurrent.CompletableFuture}, которые обеспечивают более богатое взаимодействие с асинхронной задачей и немедленную композицию.с дальнейшими шагами обработки.

Я думаю, что эта ссылка может помочь вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...