Deploy JSF composite components for shared use

2020-07-22 18:56发布

问题:

I work on a Java EE project which is planned to become quite large in future and I want to share as much code as possible. This included not only Java code, but also code for UI elements. I think about developing enterprise components based on clear defined subjects (like user administration, taxes, products) which interact on basis of messages, beans and so on. I also think about giving all these components some managed beans and JSF composites to provide some basic functionality for later use in the web UI. That's the context...

To make it concrete: Let's say I have an EAR (um.ear) for user management. Within it I have some JPA entities for database connectivity (jpa.jar) and I have some enterprise beans for the basic functionality like authentication (ejb.jar). Additionally, I want to put another jar file in (jsf.jar) which contains a managed bean LoginController for use with a composite component (with an input for username and password) login_box.xhtml which I want to place later into my web front end to different locations, depended on the actual page.

The login_box.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:composite="http://java.sun.com/jsf/composite"
    xmlns:e="http://java.sun.com/jsf/composite/login">
<h:head>
    <title>Login Box</title>
</h:head>
<h:body>
    <composite:interface>
    </composite:interface>
    <composite:implementation>
        <h:outputStylesheet library="css" name="login.css" target="head" />
        <div class="login_box">
            <h:form>
                <h:messages />
                <h:panelGrid columns="2" columnClasses="rightAlign,leftAlign">
                    <h:outputText value="Email address:" />
                    <h:inputText label="Email address" value="#{LoginController.email}"
                        required="true" size="8">
                        <f:validator validatorId="emailAddressValidator" />
                        <f:validateLength minimum="5" maximum="128" />
                    </h:inputText>
                    <h:outputText value="Password:" />
                    <h:inputText label="Password" value="#{LoginController.password}"
                        required="true" size="8" />
                </h:panelGrid>
                <h:commandButton action="${LoginController.login()}"
                    value="Login..." />
            </h:form>
        </div>
    </composite:implementation>
</h:body>
</html>

In my main application I want to work with JSF templates to generate the pages and I want to put the login box with the tag into the pages as needed.

The current setup is:

jsf.jar inside um.ear:
|- META-INF/
|   |- faces-config.xml
|   |- web.xml
|   |- sub-web.xml
|   \- resources
|       \- login
|           \- login_box.xhtml
\- com
     |- inside it the managed bean classes

The calling xhtml looks like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:e="http://java.sun.com/jsf/composite/login">
<h:head>
    <title>Title</title>
</h:head>
<h:body>
    <e:login_box /> 
</h:body>
</html>

When I use it that way, I do not get any errors and in my resulting HTML I see the instead of the wanted login box.

When I all do this within one EAR and I put the managed beans and the JSF stuff into a WAR (the classes are moved into WEB-INF/classes and the resources to WEB-INF/resources) inside the EAR everything works fine. But, how can I deploy the managed beans and the JSF stuff for later use in other EARs or JARs? I read that the /META-INF/faces-config.xml would be enough to force the container to scan for JSF stuff.

My faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
</faces-config>

I work with JBoss 6.1-Final and I tried all possible locations inside the JAR which was logical for me. I put the classes and the resource directory to root '/', to /META-INF and to WEB-INF. All of this did not work. Does anyone has suggestions, what is wrong here?

回答1:

That JAR has to end up inside /WEB-INF/lib of WAR (which can in turn be part of EAR).

Your JAR's file structure is fine.