Play Framework 异步 HTTP 请求实例

 

有时候我们的一个页面请求会执行很长时间,比如 10000 条数据的对比,假设需要花费3分钟,那么在这3分钟内该请求会一直占用着线程,如果这个时候只有一个线程,那么在这3分钟里所有页面都无法正常访问。异步 HTTP 请求就是为了解决这个问题。它会暂停当前的请求,等到执行完成后再返回结果。

1、新建一个有返回值的 Job 类

新建 Job 类用于执行耗时很长的操作。

package job;

import models.finance.BalanceReportModel;
import play.Logger;
import play.db.jpa.Transactional;
import play.jobs.Job;
import util.BalanceUtil;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 13-11-11
 * Time: 下午7:15
 * 访问记录统计任务
 */
public class BalanceJob extends Job<BalanceReportModel> {
     String period = null;

    public BalanceJob() {
    }

    public BalanceJob(String period) {
        this.period = period;
    }

    @Override
    @Transactional(readOnly = true)
    public BalanceReportModel doJobWithResult() throws Exception {
        BalanceReportModel retval = null;
        try {
            if (period != null) {
                Logger.info("-------------BalanceJob Begin");
                // 执行耗时很长的方法
                retval = BalanceUtil.excute(period);
                Logger.info("-------------BalanceJob End");

            }
        } catch (Exception e) {
            Logger.error(e, "error in BalanceJob");
        }

        return retval;
    }
}

2、在控制器的 Action 里异步执行 Job

使用 Promise 类执行异步操作,并使用 await() 方法等待返回结果。

package controllers.finance;

import job.BalanceJob;
import models.finance.BalanceReportModel;
import play.libs.F;
import play.mvc.Controller;


public class BalanceReport extends Controller {
    public static void save(String period) {
        if (period != null) {
            try {
                F.Promise<BalanceReportModel> delayedResult = new BalanceJob(period).now();
                // 等待处理完成的结果
                BalanceReportModel report = await(delayedResult);
                if(report != null) {
                    flash.success(period + " 对账完成。" + report.summary);
                }
            } catch (Exception e) {
                flash.error(e.getMessage() == null ? e.toString() : e.getMessage());
            }
        } else {
            flash.error("请选择年月。");
        }

        render();
    }
}

前一篇:
后一篇:

发表评论