简体   繁体   English

Spring MVC:控制器与异步方法之间的通信

[英]Spring MVC : Communication between Controller and Asynchronous method

What I'm trying to achieve... 我正在努力实现的目标...

From a @Controller method, get the execution status of an asynchronous process so that I can display the current progress in a HTML page. 从@Controller方法中,获取异步进程的执行状态,以便我可以在HTML页面中显示当前进度。

Scenario: 场景:

  1. User opens http://localhost/foo , controller instantiates the BackgroundAsyncService and calls workAsync method. 用户打开http://localhost/foo ,控制器实例化BackgroundAsyncService并调用workAsync方法。 The BackgroundAsyncService is autowired to controller. BackgroundAsyncService自动连接到控制器。
  2. User opens http://localhost/foo-1 and wants to see what the status of the process previously started. 用户打开http://localhost/foo-1并想查看以前启动进程的状态。 From JSP I'm using AJAX to poll the controller. 从JSP,我正在使用AJAX轮询控制器。

Questions 问题

Is it possible to get value of i after the workAsync method was called? 在调用workAsync方法之后是否可以获得i值?
What should be the topic on what I must document to so that I can arrive to an answer to the above? 我必须记录在什么文件上才能成为上述问题的答案的主题是什么?

Service class 服务等级

@Service
public class BackgroundAsyncService implements FutureService {

  private static final Logger LOGGER = Logger.getLogger(BackgroundAsyncService.class);

  @Async
  public Future<String> workAsync() {
    LOGGER.debug("workAsync begin...");
    try {
      for (int i = 0; i <= 1000; i++) {
        Thread.sleep(100);
        LOGGER.debug("i : " + i);
      }
    } catch (InterruptedException interruptedException) {
      LOGGER.error(interruptedException);
    }
    LOGGER.debug("workAsync end.");
    return new AsyncResult<String>("foo");
  }

}

I'm using 我正在使用

Spring 4.2.5.RELEASE 春天4.2.5。发布
Java 1.7 Java 1.7

Your Async method could be updating a register in a DB, a Cache or just a simple final static HashMap and then your page check the value. 您的Async方法可以更新数据库中的寄存器,缓存或仅是简单的最终静态HashMap,然后页面检查该值。 If you want to notify the page deferred result 如果要通知页面延迟结果

Have in mind that you might need a distributed cache if your application is being replicated when not using a DB. 请记住,如果在不使用数据库的情况下复制应用程序,则可能需要分布式缓存。

Using the ApplicationContext you can get BackgroundAsyncService component from spring container. 使用ApplicationContext可以从spring容器中获取BackgroundAsyncService组件。 From default it is singleton so it should be the same instance. 默认情况下,它是单例,因此它应该是同一实例。 In some action which is reference to http://localhost/foo-1 you can get "i" value. 在引用http:// localhost / foo-1的某些操作中,您可以获得“ i”值。

BackgroundAsyncService backgroundAsyncService = (BackgroundAsyncService) context.getBean(BackgroundAsyncService.class);
int i = backgroundAsyncService.getI();

You can try resize BackgroundAsyncService class: 您可以尝试调整BackgroundAsyncService类的大小:

@Service
public class BackgroundAsyncService implements FutureService {

    private static final Logger LOGGER = Logger.getLogger(BackgroundAsyncService.class);

    private int i;

    public int getI() {
        return i;
    }


    @Async
    public Future<String> workAsync() {
        LOGGER.debug("workAsync begin...");
        try {
            for (this.i = 0; this.i <= 1000; this.i++) {
               Thread.sleep(100);
               LOGGER.debug("i : " + this.i);
            }
        } catch (InterruptedException interruptedException) {
            LOGGER.error(interruptedException);
        }
        LOGGER.debug("workAsync end.");
        return new AsyncResult<String>("foo");
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM