环境
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链
那一节。