播放框架:通过作业使用高图表 JS 库的模板



这是我上一篇文章的扩展。

总结正在发生的事情:

  • 我正在使用一个每小时执行一次的作业,它将生成一个PDF作为电子邮件附件发送
  • Job没有做太多事情,只是直接调用控制器来生成PDF并发送电子邮件。我调用控制器来完成这项工作,因为我正在使用PDF模块,该模块(目前)需要HTTP请求作为其PDF处理的一部分。下面是我如何通过Job调用控制器:

    WS.url("我的/url//点///控制器"). get ();

  • 我之前使用包含highcharts JS图表的模板生成PDF的问题是,它生成了图表客户端,这对于PDF生成来说太晚了,因此我的PDF生成了减去图表。为了解决这个问题,我现在使用highcharts-serverside-export来生成图表服务器端

如果我使用上面相同的类并在浏览器中呈现模板(即直接通过控制器并忽略Job),则图表将在服务器端创建,视图将在浏览器中正确呈现。

我通过调用另一个控制器在模板中生成图表,像这样:

<img src="@{ChartGenerator.go()}">

ChartGenerator控制器基本上只是根据highcharts-server -export文档构建服务器端图表,并调用Play的renderBinary方法。

正如我所说,该模板在浏览器中与服务器端生成的图表一起呈现得很好。然而,当通过每小时执行一次的Job时,ChartGenerator.go()调用似乎不起作用。控制台吐出以下内容:

INFO  ~ /chartgenerator/go is not a URL; may be relative.

有没有人有任何想法,如何可以解决这个问题?我已经证明了它可以在没有Job的情况下工作,现在需要弄清楚为什么当通过Job时,它似乎不起作用。

编辑:根据Pere的建议,我的模板现在通过这样做调用ChartGenerator类(注意两个@):

<img src="@@{ChartGenerator.go()}">

我认为这已经让我更进一步了,现在这在日志中被吐出来了:

Error during job execution (fun.EmailJob)
Execution exception (In /fun/EmailJob.java around line 19)
RuntimeException occured : java.util.concurrent.ExecutionException: java.util.concurrent.TimeoutException: No response received after 60000
...
09:23:54,687 WARN  ~ bad URL given: http://<full url>/chartgenerator/go
java.net.SocketTimeoutException: Read timed out

如果我点击URLhttp://<在浏览器中完整的url>/chartgenerator/go, highcharts PNG文件在浏览器中被正确呈现。正如预期的那样,即使在这两个@更改之后,如果我在浏览器中呈现模板(没有pdf),模板也会正确呈现服务器端生成的图表。

编辑#2:有了这些问题,我似乎通过从模板内调用控制器来渲染图像(二进制),我想知道是否有可能将文件对象(包含图像)作为参数传递给模板的渲染(…)方法。例如,假设渲染模板的控制器这样做:

File image = ... // PNG chart as built by the highcharts-serverside-export library
...
File emailAttachment = new File("attachment.pdf");
PDF.writePDF(emailAttachment, "myTemplate.html", image); // This calls the PDF module to render the PDF from the given template and write it to the attachment.pdf File object

我想知道我是否可以以某种方式在模板中直接渲染该图像,而不必通过@@{…}?

我试着把${image}放在模板中,但这只是在屏幕上呈现attachment.pdf(有点预期)。

编辑#3:下面是ChartGenerator类的样子:

public final class ChartGenerator extends Controller {
public static void go() throws Exception {
ChartOptions options = SamplesFactory.getSingleton().createColumnBasic();
HighchartsExporter pngExporter = ExportType.png.createExporter();
File chart = new File("column-basic.png");
pngExporter.export(options, null, chart);
response.setContentTypeIfNotSet("image/png");
renderBinary(chart);
}
}

我目前只是在服务器端生成一个示例图表来证明它可以pdf格式。示例图表生成是按照highcharts-server -export文档完成的。

编辑#4:我还尝试向控制器添加一个动作方法,以允许在浏览器中使用pdf格式,服务器端生成的highchart也不会出现在pdf中,前面提到的异常仍然发生。所以我可以排除它是工作到控制器的工作流程的问题。(当然,在没有pdf格式的情况下渲染模板仍然可以正常工作)

Edit #5:为了帮助缩小问题的可能原因,我决定忽略highcharts(以及highcharts-server -export库),只使用简单的服务器端图表库jfreechart。同样,我可以在没有pdf的情况下渲染模板,但是一旦我尝试pdf包含图表的模板(通过前面提到的@@调用渲染),它最终会因为同样的原因失败(即给出的URL错误,java.net.SocketTimeoutException: Read超时)。

好的,我已经设法让它工作(最终)。这一切都源于我处于DEV模式的事实(显然是因为我仍在开发这一点功能)。但是在DEV模式下,我(默认情况下)只能访问一个线程。所以我要做的就是取消application.conf:

中的执行池注释
play.pool=3

,然后我的highchart开始在服务器上渲染,然后作为PDF的一部分插入。额外的线程用于呈现图表的请求。在这种情况下,一个线程是不够的,因此调用URL来呈现二进制图像会挂起。

似乎你的问题是一个相对url,更改代码为:

<img src="@@{ChartGenerator.go()}"> //notice double @@

生成绝对路径

最新更新