Objekt von EJB in Controller (CDI) - Klasse füllen?

beta20

Top Contributor
Hallo,

ich habe derzeit das folgende Problem:

Ich generiere in meiner EJB - Klasse eine PDF, welches den Inhalt von einer XHTML - Seite von meiner Applikation nimmt.

D.h. ich rufe eine URL von meiner Applikation auf und der Content wird wiederum in mein PDF geladen.

In meiner Controller - Klasse (CDI) benötige ich aber ein Objekt, das mir Informationen bereithält, welche dann bei der Erstellung der PDF genutzt wird.
Im Endeffekt rufe ich eine Methode in der Controller - Klasse auf, die mir den HTML Code generiert und wiederum in die XHTML - Datei schreibt. Sprich ein h:inputText wird befüllt mit HTML Code.
Hierbei benötige ich aber ein Objekt, das verschiedene Informationen enthält, welche dann bei der HTML Generierung durch richtige Daten ersetzt werden.
Sprich ich habe zuvor in dem HTML - Code Platzhalter definiert, die dann zur Laufzeit befüllt werden.

Bspw.: %Customer.Email%
-> dieser String wird dann ersetzt durch den Kunde, (welcher im Objekt gespeichert wird) und anschließend in die XHTML gesetzt (also der Wert von h:inputText)

Mein Problem ist nun:
Wie fülle ich aus meinen EJB das Objekt aus der Controller - Klasse?
Bisher habe ich immer nur den anderen Weg genutzt (also vom Controller zur EJB).

Prinzipiell ist das auch der Fall, wenn die PDF von einem User im Webinterface erstellt wird:
Controller -> EJB (dann habe ich auch kein Problem, weil ich dann das Objekt füllen kann).

Nun kann es aber auch sein, dass das PDF automatisch erstellt wird, sodass keine Aktion vom Controller kommt. Also der Weg dann vom EJB zu Controller ist.

Wie kann ich das machen?
 
Zuletzt bearbeitet:
Um das richtig zu verstehen:

Deine EJB holt sich über einen ganz normalen HTTP-Request eine HTML-Seite, die ein anderer Controller in der selben Anwendung generiert hat?

Die EJB-Aktion wird dabei durch einen anderen Controller ausgelöst, wenn der Nutzer irgendwas im Webinterface macht, etwa so:
1598270049836.png

(Den Fall. dass das PDF automatisch generiert wird erstmal kurz außer Acht gelassen)
 
Danke für die Antwort.

Im Moment befülle ich das Objekt "ObjectForReplacementObject" im JSF Layer, daher funktioniert das auch.
Nun soll das "ObjectForReplacementObject" aber im EJB Layer befüllt werden und dann an die JSF Bean übergeben werden. Denn es kann auch sein, dass die Funktion (createPDF) direkt im EJB Layer angestartet wird und das Objekt dort befüllt wird.

Anbei mal ein Schaubild:
- Im EJB Layer wird die PDF und der HTML Code ansich erzeugt
- In der EJB Bean rufe ich dann eben die Funktion "generateUrl" auf. Diese macht nichts anderes, als eine URL innerhalb der Applikation aufzurufen, also z.B. http://localhost:8080/myapp/test.xhtml
- Ab dann kommt die JSF Bean zum Einsatz.
- Innerhalb der XHTML Seite habe ich dann eben folgenden Code, der die JSF Bean aufruft:
Java:
     <h:outputText
                        value="#{generateHtmlCodeController.generateHtmlCode()}"
                        escape="false" />
- Innerhalb der JSF Bean rufe ich dann eben die generateHtmlCode(ObjectForReplacementObject object) von meiner EJB - Klasse auf, welches den HTML Code generiert. ObjectForReplacementObject object ist derzeit in der JSF Klasse.
Befüllt werden soll diese aber im EJB Layer. (Solange ich einen User habe, der das Objekt in der JSF befüllt, funktioniert das), aber das Objekt soll im EJB Container befüllt werden und an die JSF übergeben werden.
-Danach wird das generierte XHTML (also dessen Output) als Stream in das PDF geschrieben

1598272102206.png

EJB Code
Java:
@Stateless
public class PdfDocumentGenerationServiceBean implements PdfDocumentGenerationService {

    /**
     * Create PDF
     *
     * @throws IOException
     */
    public PipedOutputStream createPdf(PipedOutputStream os, DocumentDesigner documentDesigner)
            throws IOException {

        LOGGER.info("START createPdf");

        managedExecutorService.submit(() -> {

            try {
                String url = generateUrl(documentDesigner);

                PdfRendererBuilder builder = new PdfRendererBuilder();
                XRLog.setLevel(XRLog.CSS_PARSE, Level.SEVERE);
                XRLog.setLoggingEnabled(false);

                Document doc = html5ParseDocument(url, 0);
                builder.withW3cDocument(doc, url);

                builder.toStream(os);

                builder.run();
                os.close();

                return os;
            }

            catch (Exception e) {
                LOGGER.error(ExceptionUtils.getFullStackTrace(e));
            }

            return null;
        });

        LOGGER.info("END createPdf");
        return null;
    }


        /**
     * Parsen um valides XML zu bekommen
     *
     * @param urlStr
     * @param timeoutMs
     * @return
     * @throws IOException
     */
    private Document html5ParseDocument(String urlStr, int timeoutMs) throws IOException {

        URL url = new URL(urlStr);
        org.jsoup.nodes.Document doc;

        doc = Jsoup.parse(url, timeoutMs);

        // Should reuse W3CDom instance if converting multiple documents.
        return new W3CDom().fromJsoup(doc);
    }

    /**
     * URL erstellen
     *
     * @param documentDesigner
     * @return
     */
    public String generateUrl(DocumentDesigner documentDesigner) {

        try {

            String jsfPage = "mypage.xhtml";
            Subject currentUser = SecurityUtils.getSubject();

            String url = Constants.APPLICATION_URL + "/portal/" + jsfPage + ";JSESSIONID="
                    + currentUser.getSession().getId().toString() + "?documentDesignerId="
                    + documentDesigner.getIdHash();

            return url;

        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getFullStackTrace(e));
            ErrorMessage.showErrorMessage();
        }

        return null;
    }
}


JSF Bean
Java:
@Named
@ViewScoped
public class GenerateHtmlCodeController implements Serializable {

private ObjectForReplacementObject objectForReplacementObject;

public String generateHtmlCode() {

            // ObjectForReplacementObject holen -> Derzeit so impementiert, soll aber ersetzt werden mit dem Objekt aus dem EJB Layer
            ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
            Map<String, Object> sessionMap = externalContext.getSessionMap();
            ObjectForReplacementObject objectForReplacementObject = (ObjectForReplacementObject) sessionMap.get("objectForReplacementObject");
     

            String html = allGenerateHmtlCodeService.createHtmlCode(objectForReplacementObject);
            return html;
}


Bevor ich dann also createPdf() aufrufe, muss ich irgendwo ObjectForReplacementObject speichern, sodass GenerateHtmlCodeController dieses befüllte Objekte nehmen kann. Den Code wie ich das HTML erstelle, lass ich mal außen vor, das hat mit dem Problem ja nichts zu tun.

Danke für die Hilfe
 
Zuletzt bearbeitet:
Ich denke ich habe es gelöst mit:
@Inject des ObjectForReplacementObject in der EJB Klasse....
Diese kann ich dann in der Controller - Klasse so übergeben

Hänge nun aber hier:
 

Neue Themen


Zurück
Oben