我遇到有关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();
}
}
答案 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可能会对您有所帮助。