play framework 1action里调用另一个action时出现死循环

本文详细解析了在Play框架1.2.7版本下出现死循环导致堆栈溢出的问题及原因,阐述了如何避免静态方法调用引起的循环,并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境

play framework:1.2.7
java:1.7

场景

今天在写一个导出功能时,报了下面这个错误。下面说堆栈溢出,我知道是死循环造成的,但是我不明白为什么会出现死循环,因为就是单纯的请求,我又没有写递归,哪来的死循环呢?

Execution exception
InvocationTargetException occured : null


play.exceptions.JavaExecutionException
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:239)
    at Invocation.HTTP Request(Play!)
Caused by: java.lang.reflect.InvocationTargetException
    at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:557)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:508)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:484)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:479)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
    ... 1 more
Caused by: java.lang.StackOverflowError
    at java.util.Collections$UnmodifiableCollection$1.<init>(Collections.java:1064)
    at java.util.Collections$UnmodifiableCollection.iterator(Collections.java:1063)
    at play.plugins.PluginCollection.unBind(PluginCollection.java:598)
    at play.data.binding.Unbinder.unBind(Unbinder.java:33)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)
    at play.data.binding.Unbinder.unBind(Unbinder.java:110)

通过搜索文档总于明白,为什么play framework 1会出现死循环啦!

我先贴上我的代码:

/**
 * 终端3.0留存率报表
 * @param regModel
 * @param page
 * @param rows
 * @author yutao
 * @date 2018年3月22日下午7:38:18
 */
public static void activeQuery(RegistryModel regModel, int page, int rows){
    //代码省略。。。。
    if(regModel != null && regModel.getIsExport()){
        //特别说明,如果export方法写成static,那么会回调本方法,构成死循环,最终堆栈溢出
        //把其变成普通方法后,就OK
        export(regModel, queryList, "终端3.0留存率报表", titleList);
        return;
    }
    //代码省略。。。
}
/**
 * 导出 通用代码
 * @param startTime
 * @author yutao
 * @date 2018年3月23日上午11:17:42
 */
public staic void export(RegistryModel regModel, List<LinkedHashMap<String,Object>> queryList, String fileName, List<String> fields){
    //代码省略。。。
}

步骤是:
1、通过浏览器请求,会执行activeQuery这个action
2、接着执行到export(regModel, queryList, "终端3.0留存率报表", titleList);这行代码后,就报错,上面的错误。。。

说明:

在play框架中 每个public、static方法叫做Action

由于我的export也用static修饰了,所以其也是个action,也就相当于在action里面又调用了action,那么play框架是如何处理呢?
play框架的处理步骤:

1、浏览器发送一个请求到,经过路由后到了activeQuery这个方法
2、执行到了export方法后,Java调用被中断,反向路由生成器创建export()方法调用的URL
重点:但是export方法是在activeQuery方法类被调用的,并且路由里面没有给export的参数单独配置路由,所以生成出来的URL依然会路由到activeQuery这个action,然后又执行到了export,,,接着就进入死循环的节奏。

解决办法

我这个export只是当做普通的方法,并不是当做action,只需要去掉static就行了。

当做普通方法来调用就可以啦!

LoginedPowerStatisticsAction aa = new LoginedPowerStatisticsAction();
aa.export(regModel, queryList, "终端3.0留存率报表", titleList);
/**
 * 导出 通用代码
 * @param startTime
 * @author yutao
 * @date 2018年3月23日上午11:17:42
 */
public void export(RegistryModel regModel, List<LinkedHashMap<String,Object>> queryList, String fileName, List<String> fields){
    //代码省略。。。
}

参考地址:

Play 框架手册(3) – 控制器 查看action链那一节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山鬼谣me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值