将数据保存到会话时,Spring Async函数异常

时间:2019-03-07 12:36:08

标签: java spring spring-boot asynchronous

我遇到有关HttpSession的${__groovy(new File('test.csv').readLines().subList(1\,3).join('\,'),)} 任务的问题。我想以异步方法将数据保存在会话中。发生的情况是正确返回了响应,但是在会话中保存数据时出现错误。请帮忙。

我的控制器文件:

@Async

我的服务文件:

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

我的Stacktrace:

@EnableAsync
@Configuration
public class ThreadConfig {

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

2 个答案:

答案 0 :(得分:2)

在我的头上,如果我们有@Async注释,那么我认为返回类型应该是CompletableFuture类型,就像javascript中的诺言一样。
因此,通过将服务方法的返回类型从void更改为CompletableFuture<Void>,可以解决此问题。

所以我修改了如下代码:

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

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

//要在异步中获取会话对象 //这是错误的代码,但请检查适用性

所以在这里,我从HttpRequest获取会话对象并将其传递给Service,您在service处添加参数并在控制器上检查这些参数。
不要在服务或控制器处自动连接会话对象。

@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 :(得分:1)

根据Async Java文档。 void是合法退货类型。

  

就目标方法签名而言,支持任何参数类型。   但是,返回类型被限制为{@code void}或   {@link java.util.concurrent.Future}。在后一种情况下,您可以声明   更具体的{@link org.springframework.util.concurrent.ListenableFuture}或   {@link java.util.concurrent.CompletableFuture}类型可提供更丰富的功能   与异步任务交互并立即与   进一步的处理步骤。

我认为这个link可能会对您有所帮助。