当前位置: 代码迷 >> JavaScript >> JSF+EJB3架构现实项目
  详细解决方案

JSF+EJB3架构现实项目

热度:438   发布时间:2012-10-27 10:42:26.0
JSF+EJB3架构实际项目
想用JSF1.2+EJB3做个项目,先画了个架构图,拿上来让各位指点指点,有何不妥之处。。
1 楼 jones 2008-02-23  
seam已经为你做好一切了,嘿嘿
2 楼 qiujy 2008-02-23  
各位从EJB设计的角度分析下,这样行不行。。至于seam,它只是这两者的一个粘合剂。还是想先从JavaEE5的技术角度来完成一个项目。
3 楼 elfer 2008-02-27  
基本的结构是没错的,我不是很明白“显示对象”是用来做什么的
4 楼 fxy1949 2008-02-27  
In my point of view,this structure is not so good. In your pattern, you don't benifit a lot from EJB3 and JSF. It's just the same like using struts1, spring, hibernate.

The main reasons are as following:

1) “显示对象”(Is it like actionForm in Struts1?), VO and PO are not needed any more,and use POJOs(+Annotation) as EJB3 entity Bean,which could also be used as VO,and be passed to web layer.In JSF "managed beans" and JSPs( or xhtml),use these beans as JSf compoment value binding objects.

In some cases, we need add some wrapper classes which may wrap several POJOs(EJB3 entity beans) for conmunication between web layer and business logic layer.

2) In EJB3 Session Bean,"EntityManger" is used for data handling. You will soon find out that DAO layer seems unnecessary. Consider no DAO layer first,add it when absolutely needed in case very complex business logic.


In my previous project using JSF+EJB,put it simply,the pattern is "Facelets--> .xhtml--> managedBean-->EJB Session Bean--> EJB3 Entity Bean -> database".

we use POJOs(+some wrapper classes) 1)for page component binding(in jsp or .xhtml); 2)for data transfer(as VO)between layers;and 3)for data persistence(as PO). This dramatically reduces the code for data conversion.

5 楼 w_y_g 2008-02-28  
整个结构没有什么问题,挺清楚的,基本是现在大家都认可的一种方式,不过在实施的时候还需要把握的准确一些,有些问题需要注意,比如层次之间的清晰,如界面层的东西不要传递到后面去。还有就是JPA的设计了,很多基于类似于JPA的设计容易受先前的一些影响,比如走着走着就走向以前的SQL老路,等等这些。
6 楼 w_y_g 2008-02-28  
补充一点,这些年大家对EJB都不是非常关注,大家的注意力都被吸引到了Spring和Hibernate,我自己开发的一点感触,其实EJB本身还是很优秀,只是对于开发而言不太具有亲和力,写了不长的业务代码,但是一个Deploy就要等半天,所以做着做着容易丧失耐性。

最近有个想法,不过没有时间去做,因为spring和hibernate从功能上来讲,和EJB没有太大的差别,除却AOP外,spring的功能与EJB Stateless Session一样,Hibernate和CMP一样,由于这些技术都基于配置,而且基本的参数类型也比较相似,所以可以使用spring,hibernate进行开发,用EJB运行,spring和hibernate的配置文件是可以转换为EJB配置的,这样一方面可以利用spring和hibernate进行便捷的开发,同时还可以利用EJB的优异性能进行运行。
7 楼 qiujy 2008-03-02  
fxy1949 写道
In my point of view,this structure is not so good. In your pattern, you don't benifit a lot from EJB3 and JSF. It's just the same like using struts1, spring, hibernate.

The main reasons are as following:

1) “显示对象”(Is it like actionForm in Struts1?), VO and PO are not needed any more,and use POJOs(+Annotation) as EJB3 entity Bean,which could also be used as VO,and be passed to web layer.In JSF "managed beans" and JSPs( or xhtml),use these beans as JSf compoment value binding objects.

In some cases, we need add some wrapper classes which may wrap several POJOs(EJB3 entity beans) for conmunication between web layer and business logic layer.

2) In EJB3 Session Bean,"EntityManger" is used for data handling. You will soon find out that DAO layer seems unnecessary. Consider no DAO layer first,add it when absolutely needed in case very complex business logic.


In my previous project using JSF+EJB,put it simply,the pattern is "Facelets--> .xhtml--> managedBean-->EJB Session Bean--> EJB3 Entity Bean -> database".

we use POJOs(+some wrapper classes) 1)for page component binding(in jsp or .xhtml); 2)for data transfer(as VO)between layers;and 3)for data persistence(as PO). This dramatically reduces the code for data conversion.



我说的显示对象就是类似Struts的ActionFrom的东西。
很是受你的启发。我也一直觉得这样设计太过复杂,而且走入了SSH的圈套,大量的Bean的创建,属性挎贝执行效率会受影响。我目前新的设计见附图。也像你说的:Facelets --> ManagedBean -->EJB3 SessionBean(业务层) -->JPA (持久层) ---> DataBase(EIS层).这样就把Dao层去了,把VO和PO合并了,但感觉显示层的显示对象还是需要的,要不然有些数据在页面显示会有麻烦(robbin很早的一个帖子就讨论过这个问题)。请指点。。。
8 楼 fxy1949 2008-03-03  
<p>"但感觉显示层的显示对象还是需要的,要不然有些数据在页面显示会有麻烦"<br/><br/>I think if you have tried JSF a little bit, you will find out that how easy and well JSF handles this matter.<br/><br/>1) In Jsp(or xhtml) pages,the jsf components look like following:<br/><br/>&lt;div class="light col input-field"&gt;<br/>????    &lt;h:inputText id="mediaName" value="#{<span style='color: red;'>mediaBean</span>.<span style='color: #3366ff;'>media</span>.<span style='color: #ff00ff;'>name</span>}" size="50" maxlength="50" required="true"/&gt;<br/>&lt;/div&gt;<br/>?&lt;div class="light col output-field"&gt;<br/>????? &lt;h:outputText id="mediaComments" value="#{<span style='color: #ff0000;'>mediaBean</span>.<span style='color: #0000ff;'>media</span>.<span style='color: #ff00ff;'>comments</span>}"/&gt;<br/>?&lt;/div&gt;<br/> </p><p>&lt;div class="light col input-field"&gt;<br/>???? &lt;h:selectOneMenu id="format" value="#{<span style='color: #ff0000;'>mediaBean</span>.<span style='color: #3366ff;'>media</span>.<span style='color: #ff00ff;'>format</span>.id}" validator="#{mediaBean.validateSelection}" required="true"&gt;<br/>????????? &lt;f:selectItems value="#{<span style='color: #ff0000;'>mediaBean</span>.<span style='color: #00ff00;'>tapeFormatList</span>}"/&gt;<br/>????    &lt;/h:selectOneMenu&gt;<br/>/div&gt;<br/><br/><span style='color: #ff0000;'>mediaBean</span>: JSF managed Beans</p><p><span style='color: #3366ff;'>media</span>: Pojo(+annotation),entity bean</p><p><span style='color: #ff00ff;'>name,comments,format</span>: properties of Entity bean "Media" </p><p>?</p><p><span style='color: #00ff00;'>tapeFormatList</span>: List&lt;SelectItem&gt;</p><p>?</p><p>2) JSF managed bean examples:</p><p>?</p><p>public class MediaBean extends CmmManagedBean<br/>{<br/>    static final Logger log=Logger.getLogger("MediaBean");<br/>      <br/>    private Media <span style='color: #ff0000;'>media</span>;<br/><br/>private List <span style='color: #00ff00;'>tapeSegmentList;</span><br/>    <br/>    private boolean validAssetFlag;<br/>    private boolean validMediaFlag;<br/>    private boolean editFlag;<br/>    private int labelOffset;<br/>......<br/><br/>}</p><p>?</p><p>3) Entity Bean</p><p>?</p><p>package uk.co.ondemand.cmm.service.persistence;<br/><br/>import java.util.Date;<br/>import javax.persistence.*;<br/><br/>@Entity<br/>@Table(name = "CMM_MEDIA_ASC")</p><p>?</p><p>public class Media extends GenericEntity<br/>{<br/>??? @Id<br/>??? @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ")<br/>??? @SequenceGenerator(name="SEQ", sequenceName="asset_container_id", allocationSize=1)<br/>??? @Column(name = "ID", nullable = false)<br/>??? protected long id;<br/><br/>??? @Column(name = "CONTAINER_TYPE", nullable = false,insertable=false, updatable=false)<br/>??? private String containerType;<br/><br/>??? @Column(name = "NAME", nullable = false)<br/>??? private String name;</p><p>?</p><p>@Column(name = "COMMENTS") <br/>??? private String comments; </p><p>?</p><p>@JoinColumn(name = "FORMAT", referencedColumnName = "ID")<br/>??? @ManyToOne<br/>??? private CmmEnumeration format=new CmmEnumeration();</p><p>?</p><p> <span style='color: #ff0000;'>@Transient?</span> </p><p>private List foldersList;</p><p>  <span style='color: #ff0000;'>//use "Transient" annotion for additional fields not persistent,but used in JSF component value binding for carrying data.</span></p><p>?</p><p> .....</p><p><br/>??? /** Creates a new instance of Media */<br/>??? public Media() {<br/>??? }<br/>? <br/>??? /**<br/>???? * Gets the id of this AssetContainer.<br/>???? * @return the id<br/>???? */<br/>??? public long getId() {<br/>??????? return this.id;<br/>??? }<br/><br/>??? /**<br/>???? * Sets the id of this AssetContainer to the specified value.<br/>???? * @param id the new id<br/>???? */<br/>??? public void setId(long id) {<br/>??????? this.id = id;<br/>??? }<br/><br/>?.....  <br/><br/>??? public String getName() {<br/>??????? return this.name;<br/>??? }<br/><br/>??? public void setName(String name) {<br/>??????? this.name = name;<br/>??? }<br/><br/>??? public CmmEnumeration getFormat() {<br/>??????? return this.format;<br/>??? }<br/><br/>??? public void setFormat(CmmEnumeration format) {<br/>??????? this.format = format;<br/>??? }<br/>?? ......<br/>}<br/>?</p><p>4) You also can use converters for some data type conversion? between pages to models </p><p>?</p><p>faces-config.xml</p><p>...</p><p>&lt;converter&gt;</p><p>&lt;converter-for-class&gt;java.lang.Boolean&lt;/converter-for-class&gt; <br/>? &lt;converter-class&gt;uk.co.ondemand.cmm.web.jsf.YesNoBooleanConverter&lt;/converter-class&gt;<br/>?&lt;/converter&gt;<br/>?&lt;converter&gt;<br/>? &lt;converter-for-class&gt;java.util.Date&lt;/converter-for-class&gt;<br/>? &lt;converter-class&gt;uk.co.ondemand.cmm.web.jsf.CmmDateTimeConverter&lt;/converter-class&gt;<br/>?&lt;/converter&gt;<br/>?&lt;converter&gt;<br/>? &lt;converter-for-class&gt;java.sql.Timestamp&lt;/converter-for-class&gt;<br/>? &lt;converter-class&gt;uk.co.ondemand.cmm.web.jsf.CmmDateTimeConverter&lt;/converter-class&gt;<br/>?&lt;/converter&gt;<br/>.....</p><p>&lt;managed-bean&gt;<br/>? &lt;managed-bean-name&gt;mediaBean&lt;/managed-bean-name&gt;<br/>? &lt;managed-bean-class&gt;uk.co.ondemand.cmm.web.managedbean.MediaBean&lt;/managed-bean-class&gt;<br/>? &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br/>?&lt;/managed-bean&gt;</p><p>?</p><p>?</p><p>Hope this is helpful.</p><p>?</p>
9 楼 qiujy 2008-03-04  
呵呵,我对JSF不是很了解,只是用JSF做过两个项目,以前都是用JSF+Spring+Hibernate。
如果用你说的PO一对象从持久层传到页面,就有一个这样的问题,我做一个员工的查询,我的员工PO类中只有入职时间,我现在要做个组件条件查询在某个时间段入职的员工,这里是不是得再构造个类似ActionForm对象了。请指教。。
10 楼 fxy1949 2008-03-04  
In this case, if the condition is quite complicated, you might need a helper class to wrap all the condition data needed,and pass it to session bean as a parameter.

Put it very simple,for instance:

1) In Jsp(or xhtml) pages:

<div class="light col input-field">
     <h:inputText id="staffName" value="#{xxxBean.staffQueryCondition.staffName}" required="true"/>
</div>
<div class="light col input-field">
     <t:inputDate id="startTime" value="#{xxxBean.staffQueryCondition.startTime}" required="true"/>
</div>
<div class="light col output-field">
     <t:inputDate id="endTime" value="#{xxxBean.staffQueryCondition.endTime}" rquired="true"//>
</div>

......

<!-- Display search result -->
        <div id="result" class="section">
              <t:dataTable id="staffList"
                     value="#{xxxBean.staffList}" var="staff"
                     renderedIfEmpty="false"
                     preserveSort="true"
                     rowIndexVar="rowIndex"
                     rows="#{searchAssetBean.searchResultWrapper.rowsPerPage-5}"
                     styleClass="datatable"
                     preserveDataModel="false"
                     first="0"
                     varDetailToggler="detailToggler">
                     <h:column>
                         <f:facet name="header">
                             <h:outputText value="#{msg.no}"/>
                         </f:facet>
                         <h:outputText value="#{rowIndex+1}"/>
                     </h:column>
                     <h:column>
                         <f:facet name="header">
                             <t:commandSortHeader columnName="name" arrow="true" >
                                 <h:outputText value="#{msg.external_id}"/>
                             </t:commandSortHeader>
                         </f:facet>
                         <h:outputText value="#{staff.name}"/>
                     </h:column>    

                  ......
   
              </t:dataTable>
        </div>

2) JSF managed bean examples:

public class xxxBean extends xxxManagedBean
{
    static final Logger log=Logger.getLogger("xxxBean");

    private StaffQueryCondition staffQueryCondition;
    private List<Staff> staffList;
    ......

    public String query()
    {

        staffList=xxxxSessionBean.get(staffQueryCondition);

        ....

        return "xxxView";
    }

}


11 楼 qiujy 2008-03-10  
这样做,也不失为省时,省力的做法。谢谢fxy1949。
12 楼 wetouns 2008-05-28  
怎么不用SEAM?