播放框架重定向错误

时间:2012-03-03 13:13:38

标签: heroku playframework routes playframework-1.x

在本地(在Windows上)开发我的测试应用程序时,我的应用程序工作正常没有问题。

在部署到heroku(使用git)并调用特定的GET后,我收到了一个错误。花了很多时间试图调试问题 - 无法在本地再现,我找到导致它的区域(通过评论/取消注释代码区域)

这是heroku上无效的代码:

public static  void  compose(){
        compose("");
}

public static  void  compose(String content){
        render(content);
}

将上述内容改为:

 public static  void  compose(){
        String content = "";
        renderTemplate("Application/compose.html",content);
    }
    public static  void  compose(String content){
        renderTemplate("Application/compose.html",content);
    }

应用程序在heroku上工作

这是异常(从第一个代码segmant生成的异常)

Internal Server Error (500) for request GET /compose
2012-03-03T10:37:14+00:00 app[web.1]: @69hmkdf00
2012-03-03T10:37:14+00:00 app[web.1]: 
2012-03-03T10:37:14+00:00 app[web.1]: Oops: UnexpectedException
2012-03-03T10:37:14+00:00 app[web.1]: An unexpected error occured caused by exception UnexpectedException: Unexpected Error
2012-03-03T10:37:14+00:00 app[web.1]: play.exceptions.UnexpectedException: Unexpected Error
2012-03-03T10:37:14+00:00 app[web.1]: 
2012-03-03T10:37:14+00:00 app[web.1]:   at play.vfs.VirtualFile.contentAsString(VirtualFile.java:180)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.templates.TemplateLoader.load(TemplateLoader.java:69)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.templates.TemplateLoader.load(TemplateLoader.java:172)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.mvc.Controller.renderTemplate(Controller.java:640)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.mvc.Controller.render(Controller.java:695)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.mvc.Controller.renderTemplate(Controller.java:659)
2012-03-03T10:37:14+00:00 app[web.1]:   at controllers.Application.compose(Application.java:92)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:548)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.mvc.ActionInvoker.invoke(ActionInvoker.java:502)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:478)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:473)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
2012-03-03T10:37:14+00:00 app[web.1]:   at Invocation.HTTP Request(Play!)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.vfs.VirtualFile.inputstream(VirtualFile.java:111)
2012-03-03T10:37:14+00:00 app[web.1]:   at play.vfs.VirtualFile.contentAsString(VirtualFile.java:178)
2012-03-03T10:37:14+00:00 app[web.1]: Caused by: play.exceptions.UnexpectedException: Unexpected Error
2012-03-03T10:37:14+00:00 app[web.1]:   ... 12 more
2012-03-03T10:37:14+00:00 app[web.1]: Caused by: java.io.FileNotFoundException: /app/app/views (Is a directory)
2012-03-03T10:37:14+00:00 app[web.1]:   at java.io.FileInputStream.<init>(FileInputStream.java:137)
2012-03-03T10:37:14+00:00 app[web.1]:   at java.io.FileInputStream.open(Native Method)
2012-03-03T10:37:14+00:00 app[web.1]:   ... 13 more
2012-03-03T10:37:14+00:00 app[web.1]:   at play.vfs.VirtualFile.inputstream(VirtualFile.java:109)

路由文件相关行

  

* /撰写Application.compose

我的问题是

  • 我做错了什么(以及为什么改变我做了修复)?
  • 以及它为什么不在本地重现?

2 个答案:

答案 0 :(得分:0)

如果你改变它,上面的代码应该可以正常工作;

public static  void  compose(){
        String a = "";
        compose(a);
}

public static  void  compose(String content){
        render(content);
}

因为在呈现HTML之前需要为空字符串保留一些内存。

答案 1 :(得分:0)

在Play框架版本1.2.x中,渲染方法源如下所示:

protected static void render(Object... args) {
    String templateName = null;
    if (args.length > 0 && args[0] instanceof String && LocalVariablesNamesTracer.getAllLocalVariableNames(args[0]).isEmpty()) {
        templateName = args[0].toString();
    } else {
        templateName = template();
    }
    renderTemplate(templateName, args);
}

可以看出,如果第一个参数是一个字符串,并且它与局部变量的名称不匹配 - 它被解释为模板名称。因此,将静态空字符串作为第一个参数传递被视为呈现具有空名称的模板的请求 - 因此发生“找不到文件(...是目录)”错误。

确实有一个带有任何名称的局部变量并将该变量作为参数传递应该可以使它工作。

似乎:

String tmp = "anything";
render(tmp);

截然不同
render("anything");

第二次调用将显式查找名为“anything”的模板。