分享

利用JSF、SpringFramework和Hibernate构建Web应用的实例讲述(5)

 WindySky 2007-07-02

Wire everything up

由于篇幅所限,我们仅举例说明,范例中use case CreateProduct展示了如何装配和构建应用,在详细讲述细节前,我们利用sequence图(图7)来说明所有层的end-tp-end整合。

表示层

表示层实现包括创建JSP页面、定义页导航、创建和配置backing bean以及将JSF与业务逻辑层整合。

◆JSP page:createProduct.jsp是用来创建新产品的页面,它包含UI组件并将组件打包成ProductBean,ValidateItemsRange标签用来验证用户选择的种类数量,对每一个产品至少要有一个种类被选中。

◆页面导航:应用中的导航被定义在应用的配置文件faces-navigation.xml中,CreateProduct的导航准则如下:

            

*   

createProduct

/createProduct.jsp



/createProduct.jsp



success

/uploadImage.jsp



retry

/createProduct.jsp



cancel

/productList.jsp



◆Backing bean:ProductBean不仅包含有将数据映射到页面上的UI组件的属性,还包括三个action:createAction、editAction和deleteAction,下面是createAction方法的代码:

            

public String createAction() {

try {

Product product = ProductBeanBuilder.createProduct(this);

//Save the product.

this.serviceLocator.getCatalogService().saveProduct(product);

//Store the current product id inside the session bean.

//For the use of image uploader.

FacesUtils.getSessionBean().setCurrentProductId(this.id);

//Remove the productList inside the cache.

this.logger.debug("remove ProductListBean from cache");

FacesUtils.resetManagedBean(BeanNames.PRODUCT_LIST_BEAN);

} catch (DuplicateProductIdException de) {

String msg = "Product id already exists";

this.logger.info(msg);

FacesUtils.addErrorMessage(msg);

return NavigationResults.RETRY;

} catch (Exception e) {

String msg = "Could not save product";

this.logger.error(msg, e);

FacesUtils.addErrorMessage(msg + ": Internal Error");

return NavigationResults.FAILURE;

}

String msg = "Product with id of " + this.id + " was created successfully.";

this.logger.debug(msg);

FacesUtils.addInfoMessage(msg);

return NavigationResults.SUCCESS;

}

◆Managed-bean声明:ProductBean必须在JSF配置文件faces-managed-bean.xml中配置:

            

Backing bean that contains product information.  

productBean

catalog.view.bean.ProductBean

request      

id

#{param.productId}



serviceLocator

#{serviceLocatorBean}



◆表示层和业务逻辑层之间的整合: ServiceLocator抽象了查找服务的逻辑,在范例应用中,ServiceLocator被定义为一个接口,该接口实现为一个JSF的 managed bean,即ServiceLocatorBean,它将在Spring的application context中寻找服务:

            

ServletContext context = FacesUtils.getServletContext();

this.appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(context);

this.catalogService = (CatalogService)this.lookupService(CATALOG_SERVICE_BEAN_NAME);

this.userService = (UserService)this.lookupService(USER_SERVICE_BEAN_NAME);



业务逻辑层

◆业务对象:由于采用Hibernate提供持久化,因此Product和Category两个业务对象需要为它们的所有field提供getter和setter。

◆业务服务:CatalogService接口中定义了所有的与Catalog management相关的服务:

            

public interface CatalogService {

public Product saveProduct(Product product) throws CatalogException;

public void updateProduct(Product product) throws CatalogException;

public void deleteProduct(Product product) throws CatalogException;

public Product getProduct(String productId) throws CatalogException;

public Category getCategory(String categoryId) throws CatalogException;

public List getAllProducts() throws CatalogException;

public List getAllCategories() throws CatalogException;

}



◆Spring Configuration:这里是CatalogService的Spring配置:

            

PROPAGATION_REQUIRED,readOnly

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED



◆Spring和Hibernate的整合:下面是HibernateSessionFactory的配置:

            

<!-- Hibernate SessionFactory Definition -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">

<property name="mappingResources">

<list>

<value>catalog/model/businessobject/Product.hbm.xml</value>

<value>catalog/model/businessobject/Category.hbm.xml</value>

<value>catalog/model/businessobject/User.hbm.xml</value>

</list>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>

<prop

key="hibernate.cache.provider_class">net.sf.hibernate.cache.HashtableCacheProvider</prop>

</props>

</property>

<property name="dataSource">

<ref bean="dataSource"/>

</property>

</bean>

CatalogDao uses HibernateTemplate to integrate between Hibernate and Spring. Here‘s the

configuration for HibernateTemplate:

<!-- Hibernate Template Defintion -->

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate.HibernateTemplate">

<property name="sessionFactory"><ref bean="sessionFactory"/></property>

<property name="jdbcExceptionTranslator"><ref bean="jdbcExceptionTranslator"/></property>

</bean>



Integration层

Hibernate通过xml配置文件来映射业务对象和关系数据库,在JCatalog中,Product.hbm.xml表示了Product对象的映射,Category.hbm.xml则用来表示Category的映射,Product.hbm.xml如下:

            

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate./hibernate-mapping-2.0.dtd">

<hibernate-mapping package="catalog.model.businessobject">

<class name="Product" table="product">

<id name="id" column="ID" unsaved-value="null">

<generator class="assigned"/>

</id>

<property name="name" column="NAME" unique="true" not-null="true"/>

<property name="price" column="PRICE"/>   

<property name="width" column="WIDTH"/>     

<property name="height" column="height"/>     

<property name="description" column="description"/>  

<set name="categoryIds" table="product_category" cascade="all">

<key column="PRODUCT_ID"/>

<element column="CATEGORY_ID" type="string"/>

</set>

</class>

</hibernate-mapping>

CatalogDao is wired with HibernateTemplate by Spring:

<!-- Catalog DAO Definition: Hibernate implementation -->

<bean id="catalogDao" class="catalog.model.dao.hibernate.CatalogDaoHibernateImpl">

<property name="hibernateTemplate"><ref bean="hibernateTemplate"/></property>

</bean>

结论

本文主要讲述了如何将JSF与Spring、Hibernate整合在一起来构建实际的Web应用,这三种技术的组合提供了一个强大的Web应用开发框架。在Web应用的高层设计中应该采用多层构架体系,JSF非常适合MVC设计模式以实现表示层,Spring可用在业务逻辑层中管理业务对象,并提供事物管理和资源管理等,Spring与Hibernate结合的非常出色,Hibernate是强大的O/R映射框架,它可以在integration层中提供最好的服务。

通过将整个Web应用分割成多层,并借助于“编程到接口”,应用程序的每一层所采用的技术都是可替换,例如Struts可以用来替换JSF,JDO可替换Hibernate。各层之间的整合不是不值得研究,采用IoC和ServiceLocator设计模式可使得整合非常容易。JSF提供了其它Web框架欠缺的功能,然而,这并不意味着你马上抛弃Struts而开始使用JSF,是否采用JSF取决于项目目前的状况和功能需求,以及开发团队的意见等。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多