2011-12-14 15 views
6

Questa è un'estensione di una previous post creata.Play Framework: PDF'in un modello che utilizza la libreria JS highcharts tramite un Job

Per riassumere ciò che sta succedendo:

  • Sto usando un lavoro che viene eseguito ogni ora che genererà un PDF da inviare come allegato di una e-mail
  • il lavoro non viene fare molto ma chiamare direttamente su un controller per generare il PDF e inviare l'e-mail. Io chiamo un controller per fare il lavoro dal momento che sto usando il modulo PDF che (attualmente) richiede una richiesta HTTP come parte della sua elaborazione PDF. Ecco come chiamo il controller tramite Job:

    WS.url ("mio/url/che/punti/a/il/controller"). Get();

  • Il mio precedente problema con la creazione di PDF in un modello che include un diagramma JS di diagrammi elevati è che ha generato il grafico lato client, che era troppo tardi per la generazione di PDF e quindi il mio PDF è stato prodotto meno il grafico. Per aggirare il problema, ora sto usando highcharts-serverside-export per generare il lato server grafico

Se io uso le stesse classi sopra e rendere il modello nel browser (vale a dire passare attraverso il controller direttamente e ignorare il lavoro) , il grafico viene creato lato server e la vista viene visualizzata correttamente nel browser.

sto generando il grafico nel modello chiamando un altro controller in questo modo:

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

Il controller ChartGenerator solo costruisce fondamentalmente la serverside tabella secondo la documentazione Highcharts-serverside-export e chiama Giochiamo renderBinary metodo.

Come ho già detto, il modello viene visualizzato correttamente nel browser con il grafico generato sul lato server. Tuttavia, quando si passa attraverso il processo che viene eseguito ogni ora, la chiamata ChartGenerator.go() non sembra funzionare. La console sputa questo fuori:

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

Qualcuno ha qualche idea come questo può essere fissato? Ho dimostrato che funziona meno il lavoro e ora ho bisogno di capire perché quando si passa attraverso il lavoro, non sembra funzionare.

Edit: Come da suggerimento di Pere, il mio modello ora chiama la classe ChartGenerator in questo modo (notare il doppio @ 's):

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

Penso che mi ha preso un po' più con la società questo sempre sputato nei registri:

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 

Se mi ha colpito l'URL di http: // < url completo>/chartgenerator/go nel browser, il file le Highcharts png ottiene il rendering ed nel browser correttamente. E come previsto, anche dopo questa doppia modifica, se rendo il modello nel browser (senza fare il pdf), il modello viene visualizzato correttamente con il grafico generato sul lato server.

Edit # 2: Con questi problemi che sembrano avere chiamando un controller all'interno di un modello per il rendering di un'immagine (binario), mi chiedo se sia possibile far passare l'oggetto file (contenente il immagine) come parametro del metodo di rendering (...) per il modello. Così, per esempio, diciamo che il controller che rende il modello fa questo:

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 

Mi chiedo se potessi in qualche modo rendere l'immagine nel modello direttamente senza dover passare attraverso il @@ {... } modo?

Ho provato a mettere $ {immagine} nel modello, ma che appena resa attachment.pdf sullo schermo (kinda previsto).

Modifica # 3: Ecco ciò che la classe ChartGenerator assomiglia:

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); 
    } 
} 

Attualmente sto solo la generazione di un lato server grafico di esempio per dimostrare che può essere pdf'ed. La generazione del diagramma di esempio viene eseguita secondo la documentazione di highcharts-serveride-export.

Modifica # 4: Ho anche provato ad aggiungere un metodo di azione per il controller per consentire pdf'ing mentre nel browser, e il lato server generato highchart anche non appare nel PDF e l'eccezione già citato ancora si verifica. Quindi posso escludere che si tratti di un problema con il flusso di lavoro di Job to Controller. (Ovviamente rendere il modello senza pdf'ing funziona ancora bene)

Modifica # 5: Per aiutare a restringere le possibili cause del problema, ho deciso di ignorare Highcharts (insieme con la libreria Highcharts-serverside-export) e basta usare il semplice jfreechart della libreria di grafici lato server. Ancora una volta, posso renderizzare il modello senza fare il pdf, ma appena provo e pdf un modello che include un grafico (reso tramite la summenzionata chiamata @@), finisce per fallire per lo stesso motivo (es. URL errato dato, java.net.SocketTimeoutException: Read time out).

risposta

1

Va bene, sono riuscito a farlo funzionare (finalmente). Tutto deriva dal fatto che sono in modalità DEV (ovviamente perché sto ancora sviluppando questo bit di funzionalità). Ma mentre in modalità DEV, I (per impostazione predefinita) ha accesso solo a un thread. Quindi tutto quello che dovevo fare era rimuovere il commento dalla piscina esecuzione in application.conf:

play.pool=3 

e poi il mio highchart iniziato il rendering sul server e poi sempre inserita come parte del PDF. Il thread aggiuntivo è stato utilizzato per la richiesta di rendering del grafico. Un thread non era sufficiente per questo scenario e quindi la chiamata all'URL per rendere il binario dell'immagine bloccato.

+0

+1 grande scoperta! :) –

+0

Ho lo stesso problema, Funziona nel mio dispositivo DEV dopo aver modificato come hai menzionato. Ma funziona in ambiente Prod, funziona in modalità prod. Ho pensato che sarebbero necessari processori nb + 1, quindi ho commentato questa riga per la modalità prod. Non funziona, e ho un commento e ancora non ha funzionato. Quale potrebbe essere la ragione? –

0

Sembra che il tuo problema è un URL relativo, modificare il codice a:

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

per generare percorsi assoluti

+0

grazie per il suggerimento Pere. Ho aggiornato il mio OP con i dettagli di questa doppia correzione @@. – digiarnie

+0

Potremmo aver bisogno del codice nel metodo go() per vedere quale potrebbe essere il problema. Difficile da indovinare adesso –

+0

Ho aggiunto il metodo go() nell'OP. – digiarnie

Problemi correlati