Version 4

    原文:开发基于JBoss AS 7.2.0的Java EE程序 - 03.如何创建EJB、WAR、Connector和EAR工程

    英文:JBoss AS 7.2.0 - Java EE application development - 03.How to create EJB,WAR,Connector and EAR projects

     

     

    概述

    本文描述如何创建基于JBoss AS 7.2的Java EE程序的EJB、WAR、Connector和EAR工程。

     

    1. 创建 Enterprise Application Project

    1.1 在Eclipse中先创建一个Server

              

     

              

     

              

     

              

           

     

               点击上图的“Finish”按钮,一个JBoss AS Server就创建好了。

     

     

              

     

               启动日志:

              

     

                现在我们停止JBoss AS 7.2

               

     

     

     

    1.2 创建 Enterprise Application Project

    依次导航菜单: "File" > "New" > "Project ..." ,在弹出来的界面中,选择 "Java EE > Enterprise Application Project",如下:

            

     

             点击上图中的“Next”按钮。

     

            

     

            点击上图中的“Next”按钮。

     

            注意选中“Generate application deployment descriptor”勾选框:

           

     

           

     

           点击上图中的“New Module...”按钮。

     

           我们修改自动生成的modules名字:

          

     

           点击上图中的“Finish”按钮。   

     

           结果:

          

     

          

     

          设置文本编辑器的编码格式:

          

     

     

     

     

    现在我们把application.xml中的 <context-root>ybxiang-forum-war</context-root> 改成 <context-root>/</context-root>

     

     

     

    2. 为ybxiang-forum-war 添加基本功能

    2.1 添加JSF功能

     

           

     

          

     

     

    结果:

    (a) web.xml内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <display-name>ybxiang-forum-war</display-name>
      <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
      </servlet-mapping>
    </web-app>

     

    (b) 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_1.xsd"
        version="2.1">

     

    </faces-config>

     

     

    我们为web.xml删除 <display-name>元素,并添加一些内容,如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0" 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-app_3_0.xsd">
        <context-param>
          <param-name>PARAMETER_ENCODING</param-name>
          <param-value>UTF-8</param-value>
        </context-param>
        <context-param>
            <param-name>javax.faces.PROJECT_STAGE</param-name>
            <param-value>Development</param-value>
        </context-param>

        <context-param>
            <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
            <!-- do NOT use 'server' value, because it will cause javax.faces.application.ViewExpiredException -->
            <param-value>client</param-value>
        </context-param>

        <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>/faces/*</url-pattern>
        </servlet-mapping>
        <session-config>
            <session-timeout>600</session-timeout>
        </session-config>
        <welcome-file-list>
            <welcome-file>faces/index.xhtml</welcome-file>
        </welcome-file-list>

    </web-app>

     

    其中:

    • PARAMETER_ENCODING:设置 表单(form)提交内容的编码格式。
    • javax.faces.STATE_SAVING_METHOD:用于将session状态信息存储在客户端,如果使用'server',那么客户端可能出现异常:javax.faces.application.ViewExpiredException
    • session-timeout:设置会话超时时间,单位是分钟。
    • welcome-file-list:设置欢迎页

     

     

    2.2 模板

     

    (a) template/template.xhtml

    <?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">
        <h:head>
                <title>
                    <ui:insert name="title"/>
                    <h:outputText value=" - www.javaarm.com" />
                </title>
                <link rel="shortcut icon" href="#{request.contextPath}/img/favicon.ico"/>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <link rel="stylesheet" type="text/css" media="all" href="#{request.contextPath}/css/template.css" />
                <ui:insert name="headMetaData"/>
        </h:head>
        <!-- make the whole body in center -->
        <style type="text/css">
            <!--
            body{ margin:0 auto;}
            -->
        </style>
        <h:body style="width:1000px;" styleClass="yui-skin-sam" >
            <a name="header" id="header" />
            <ui:include src="/template/navigator.xhtml" />
            <hr class="separator" />
            <f:view>
                <h:messages id="messages" globalOnly="true" styleClass="message"
                    errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg"
                    rendered="#{showGlobalMessages != 'false'}"/>
                <ui:insert name="body" />
            </f:view>
            <hr class="separator" />
            <a name="footer" id="footer" />     
            <h:outputLink value="#{request.contextPath}/faces/index.xhtml" ><h:outputText value="Home" /></h:outputLink>
            <h:outputText value="  " />
            <h:outputLink rendered="#{not forPrint}" value="#header"><h:outputText value="Header" /></h:outputLink>
            <hr class="separator" />
            <ui:include src="/template/footer.xhtml" />
        </h:body>
    </html>

     

     

    (b) template/navigator.xhtml

    <?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">

     

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"

        xmlns:ui="http://java.sun.com/jsf/facelets"

        xmlns:h="http://java.sun.com/jsf/html">

        <div>

            <h:form id="search" >

                <table width="100%" border="0" cellpadding="0" cellspacing="0" >

                    <tr>

                        <td width="50%">

                            <h:outputLink value="#{request.contextPath}/faces/index.xhtml" >

                                <h:outputText value="Home" />

                            </h:outputLink>

                        </td>

                        <td width="50%" style="text-align: right;" >

                        </td>

                    </tr>

                    <tr>

                        <td colspan="100">

                            <h:graphicImage value="#{request.contextPath}/img/biggrin.gif" style="border:0px;" />

                            <h:outputText value=" " />

                        </td>

                    </tr>

                </table>

            </h:form>

        </div>   

    </ui:composition>

     

     

     

    (c) template/footer.xhtml

    <?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">

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"

        xmlns:ui="http://java.sun.com/jsf/facelets"

        xmlns:h="http://java.sun.com/jsf/html"

        xmlns:f="http://java.sun.com/jsf/core">

        <div style="margin-top: 2px; text-align: center">

            <h:outputText value="www.jdetail.com" />

        </div>   

    </ui:composition>

     

    (d) css/template.css

    .separator{
        border:0px; border-top: 1px dashed #6293bb;
    }
    .topic_separator{
        text-decoration: none;background: #ffffff
    }
    .linelessLink{
        text-decoration: none;
    }
    .message li {
        background: no-repeat left center;
        padding-top: 1px;
        padding-left: 20px;
        margin-left: 3px;
    }
    .message li.infomsg {
        background-image: url(../img/msginfo.png);
    }
    .message li.errormsg {
        background-image: url(../img/msgerror.png);
    }
    .message li.warnmsg {
        background-image: url(../img/msgwarn.png);
    }

     

    (e)index.xhtml

    <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"

                    xmlns:ui="http://java.sun.com/jsf/facelets"

                    xmlns:f="http://java.sun.com/jsf/core"

                    xmlns:h="http://java.sun.com/jsf/html"
                   template="/template/template.xhtml">

     

       <ui:define name="title">

            <h:outputText value="JAVA and ARM research" />

        </ui:define>

     

       <ui:define name="headMetaData">

            <!-- 'head' module is used to include css/script files, do NOT display anything in it. -->

            <link rel="stylesheet" type="text/css" media="all" href="#{request.contextPath}/css/index.css" />

        </ui:define>

     

       <ui:define name="body">

            <div>

                <div class="div-domain"><h:outputText value="Administration" /></div>

            </div>

        </ui:define>

    </ui:composition>

     

     

     

    2.4 测试

           

     

     

         

     

         

     

    效果图:

          

     

     

    3. ybxiang-forum-ejb 添加基本功能

    3.1 添加JPA功能

              

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    现在我们把 persistence.xml 修改如下:

    <?xml version="1.0" encoding="UTF-8"?>

    <persistence version="2.1"

        xmlns="http://java.sun.com/xml/ns/persistence"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_1.xsd">

     

        <persistence-unit name="ybxiang-forum-persistence-unit">

            <jta-data-source>java:jboss/datasources/ybxiangForumMySqlDataSource</jta-data-source>

            <properties>

                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>

                <property name="hibernate.hbm2ddl.auto" value="update"/>

                <property name="hibernate.show_sql" value="false"/>

                <property name="hibernate.format_sql" value="true"/>

            </properties>

        </persistence-unit>

    </persistence>

     

     

     

    3.2 数据源配置

    参见:开发基于JBoss AS 7.2.0的Java EE程序 - 02.如何配置MySql数据源

     

     

    3.3 测试

    重启 JBoss AS 7.2,相关日志如下:

     

    16:07:21,093 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-6) JBAS010400: Bound data source [java:jboss/datasources/ybxiangForumMySqlDataSource]
    ...
    16:07:23,078 INFO  [org.hibernate.Version] (ServerService Thread Pool -- 58) HHH000412: Hibernate Core {4.2.0.CR1}
    16:07:23,109 INFO  [org.hibernate.cfg.Environment] (ServerService Thread Pool -- 58) HHH000206: hibernate.properties not found
    16:07:23,109 INFO  [org.hibernate.cfg.Environment] (ServerService Thread Pool -- 58) HHH000021: Bytecode provider name : javassist
    16:07:23,453 INFO  [org.hibernate.ejb.Ejb3Configuration] (ServerService Thread Pool -- 58) HHH000204: Processing PersistenceUnitInfo [
        name: ybxiang-forum-persistence-unit
        ...]

     

    蓝色的日志意味着我们在persistence.xml中的配置已经生效。

     

     

     

    4. classpath 配置

    4.1 EJB项目的classpath

    • 我们在ejb项目中,通常要用到javax.persistence.*,因此,我们需要把JPA的API jar包添加到ejb项目的classpath中。
    • 同理,j2ee程序,通常需要开发EJB的,所以ejb对应的jar包也需要包含到ejb项目的classpath中。
    • 如 果我们想要使用JBoss logging,那么我们还需要引入jboss logging的jar包。当然,我们也可以使用JDK logging,我们强烈推荐使用JDK logging。JBoss log系统会正确把日志打印到 server.log 中的,参见 JBoss7.1.1 > article > JBoss Logging
    • 我 们通常会把密码以hash的方式存储到数据库。因此,还需要jboss的picket box对应的jar包。org.jboss.crypto.CryptoUtil和org.jboss.security.auth.spi.Util, 都可以用于对密码计算Hash!

    注意:所有这些jar包,都可以在$JBOSS_HOME/modules/system/layers/base下面的那些子目录中找到。

     

    现在,我们的EJB项目的classpath如下:

            

     

     

     

    4.2 WAR 项目的classpath

    • 基于JSF的WAR项目中,通常要用到JSF API包。
    • WAR项目,通常会用到servlet API,所以这个包也得加上。
    • 我们通常会把EJB通过注解“@EJB”注入到JSF的MBean中,用于读写数据,所以,EJB对应的API包也要加入。

    现在,我们的war项目的classpath如下:

             

     

     

     

     

     

    5 网站规划

    我们要为本网站实现下列功能:

    • 用户注册、电子邮件激活账号、基于JAAS登陆、电子邮件找回密码、控制台设置个人信息。
    • 分页显示文章
    • 文件上传