关于JSF1.2 + Spring2.5 + Hibernate3 + Facelets + Annotation整合配置的参考

    提供一个整合JSF,Spring, Hibernate(JPA), Facelets, 及Annotation的基础环境。对于刚开始使用这种组合的项目,或许可以参考一下,相信使用以上整合环境的项目还是比较少。我一直很喜欢这种组合,JSF组件式的开发,Spring, Hibernate对BackingBean及数据源的管理,Facelets的模版化技术,以及Annotation都大大简化了开发。
    JSF组件的高度封装及高可重用性,使得页面代码在非常简单的情况下快速实现非常复杂的功能。Spring,Hibernate的整合进一步简化了JSF的开发,特别是Annotation的配置使得现在几乎完全不需要去XML中配置Bean这些繁琐的事情,这确实很繁琐,特别是如果再加上配置JSF的导航规则,在开发过程中经常要去碰这些东西,确实很麻烦,又容易出错。所以如果项目允许,还是推荐使用Annotation,并且这也是很多专家推荐的。作为Java5新加入的特性,它确实对开发带来了很大的方便,以前不怎么喜欢,不过现在感觉它很有前途!另一个就是Facelets了,这可是用来替代JSP的视图描述技术,Facelets模版化的威力可是非常强大,虽然不少人认为它的自定义标签功能更强大,具体介绍还是大家网上搜一下吧。下面看一下大概的配置过程,仅供参考,因为网上也有不少类似的教程,所以不作啰嗦,仅取重点。

环境:Netbeans7, Tomcat6.0.18, MySQL5

相关框架:JSF1.2,Spring2.5,Hibernate3(JPA), Facelets, Annotation, MyFaces(附加), QFaces(附加)

1.相关引用的jar包

可以看到引用的jar还是不少,至少加起来有43.2M。最后一个是我自定义的组件包qfaces-1.2.1,刚升级支持Facelets(qfaces在1.2及之前未能够支持Facelets而没有说明,使一些用Facelets的朋友遇到麻烦,这里道歉哦。)

2.web.xml文件配置

  1  <? xml version="1.0" encoding="UTF-8" ?>
  2  < web-app  version ="2.5"  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_2_5.xsd" >
  3       < context-param >
  4           < param-name > com.sun.faces.verifyObjects </ param-name >
  5           < param-value > false </ param-value >
  6       </ context-param >
  7       < context-param >
  8           < param-name > com.sun.faces.validateXml </ param-name >
  9           < param-value > true </ param-value >
 10       </ context-param >
 11       < context-param >
 12           < param-name > javax.faces.STATE_SAVING_METHOD </ param-name >
 13           < param-value > client </ param-value >
 14       </ context-param >
 15 
 16       <!--  Config:Facelets  -->
 17 
 18       < context-param >
 19           < param-name > javax.faces.DEFAULT_SUFFIX </ param-name >
 20           < param-value > .xhtml </ param-value >
 21       </ context-param >
 22 
 23       <!--  Config:Spring  -->
 24 
 25       < servlet >
 26           < servlet-name > dispatcher </ servlet-name >
 27           < servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class >
 28           < load-on-startup > 2 </ load-on-startup >
 29       </ servlet >
 30       < servlet-mapping >
 31           < servlet-name > dispatcher </ servlet-name >
 32           < url-pattern > *.htm </ url-pattern >
 33       </ servlet-mapping >
 34       < listener >
 35           < listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
 36       </ listener >
 37       < listener >
 38           < listener-class > org.springframework.web.context.request.RequestContextListener </ listener-class >
 39       </ listener >
 40       < listener >
 41           < listener-class > com.sun.faces.config.ConfigureListener </ listener-class >
 42       </ listener >
 43       < listener >
 44           < listener-class > com.sun.faces.application.WebappLifecycleListener </ listener-class >
 45       </ listener >
 46 
 47       <!--  Config:MyFaces  -->
 48 
 49       < filter >
 50           < filter-name > MyFacesExtensionsFilter </ filter-name >
 51           < filter-class >
 52              org.apache.myfaces.webapp.filter.ExtensionsFilter
 53           </ filter-class >
 54           < init-param >
 55               < param-name > uploadMaxFileSize </ param-name >
 56               < param-value > 100m </ param-value >
 57           </ init-param >
 58           < init-param >
 59               < param-name > uploadThresholdSize </ param-name >
 60               < param-value > 80k </ param-value >
 61           </ init-param >
 62       </ filter >
 63       < filter-mapping >
 64           < filter-name > MyFacesExtensionsFilter </ filter-name >
 65           < servlet-name > Faces Servlet </ servlet-name >
 66       </ filter-mapping >
 67       < filter-mapping >
 68           < filter-name > MyFacesExtensionsFilter </ filter-name >
 69           < url-pattern > /faces/myFacesExtensionResource/* </ url-pattern >
 70       </ filter-mapping >
 71 
 72       <!--  Config:QFaces  -->
 73 
 74       < servlet >
 75           < servlet-name > QFaces </ servlet-name >
 76           < servlet-class > name.huliqing.qfaces.FacesServlet </ servlet-class >
 77       </ servlet >
 78       < servlet-mapping >
 79           < servlet-name > QFaces </ servlet-name >
 80           < url-pattern > *.qfaces </ url-pattern >
 81       </ servlet-mapping >
 82 
 83       <!--  End  -->
 84 
 85       < servlet >
 86           < servlet-name > Faces Servlet </ servlet-name >
 87           < servlet-class > javax.faces.webapp.FacesServlet </ servlet-class >
 88           < load-on-startup > 1 </ load-on-startup >
 89       </ servlet >
 90       < servlet-mapping >
 91           < servlet-name > Faces Servlet </ servlet-name >
 92           < url-pattern > *.faces </ url-pattern >
 93       </ servlet-mapping >
 94       < session-config >
 95           < session-timeout >
 96              30
 97           </ session-timeout >
 98       </ session-config >
 99       < welcome-file-list >
100           < welcome-file > welcome.jsp </ welcome-file >
101       </ welcome-file-list >
102       </ web-app >
103 

这是web.xml,可以看到默认的配置很简单,并没有什么特别的,在网上大都可以看到类似。相关部分都有注识。上面Facelets配置的默认后缀就是xhtml了,这样当我们访问如 test.faces这样的页面时,就会由Facelets的ViewHandler最后解析到test.xhtml。所以我们的页面后缀就需要是.xhtml。另外两个额外的配置MyFaces,QFaces,如果不需要,都可以直接注释掉,不会影响。

3.faces-config.xml
文件位置: WEB-INF/faces-config.xml

 1  <? xml version='1.0' encoding='UTF-8' ?>
 2 
 3  <!--  =========== FULL CONFIGURATION FILE ==================================  -->
 4 
 5  < faces-config  version ="1.2"  
 6      xmlns ="http://java.sun.com/xml/ns/javaee"  
 7      xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  
 8      xsi:schemaLocation ="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd" >
 9       < application >
10           <!--  国际化支持  -->
11           < locale-config >
12               < default-locale > zh </ default-locale >
13               < supported-locale > zh </ supported-locale >
14               < supported-locale > en </ supported-locale >
15           </ locale-config >
16           < message-bundle > resource </ message-bundle >
17           < resource-bundle >
18               < base-name > resource </ base-name >
19               < var > text </ var >
20           </ resource-bundle >
21           <!--  Facelet, Spring  -->
22           < view-handler >
23              com.sun.facelets.FaceletViewHandler
24           </ view-handler >
25           < variable-resolver >
26              org.springframework.web.jsf.DelegatingVariableResolver
27           </ variable-resolver >
28       </ application >
29  </ faces-config >

重点注意Facelets view-handler及Spring variable-resolver的配置就可以。

4.dispatcher-servlet.xml
文件位置:WEB-INF/dispatcher-servlet.xml

<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns ="http://www.springframework.org/schema/beans"
       xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p
="http://www.springframework.org/schema/p"
       xmlns:aop
="http://www.springframework.org/schema/aop"
       xmlns:tx
="http://www.springframework.org/schema/tx"
       xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
>
    
    
< bean  class ="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
   

    
< bean  id ="urlMapping"  class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >
        
< property  name ="mappings" >
            
< props >
                
< prop  key ="/index.htm" > indexController </ prop >
            
</ props >
        
</ property >
    
</ bean >
    
    
< bean  id ="viewResolver"
          class
="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix
="/WEB-INF/jsp/"
          p:suffix
=".jsp"   />
   

    
< bean  name ="indexController"
          class
="org.springframework.web.servlet.mvc.ParameterizableViewController"
          p:viewName
="index"   />
    
</ beans >

这也是Spring的默认配置

5.applicationContext.xml
文件位置:WEB-INF/applicationContext.xml

<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns ="http://www.springframework.org/schema/beans"
       xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p
="http://www.springframework.org/schema/p"
       xmlns:aop
="http://www.springframework.org/schema/aop"
       xmlns:tx
="http://www.springframework.org/schema/tx"
       xmlns:context
="http://www.springframework.org/schema/context"
       xsi:schemaLocation
="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd"
>
    
< aop:aspectj-autoproxy />
    
< context:annotation-config />
    
< context:component-scan  base-package ="name.huliqing.magic" />
    
< bean  id ="propertyConfigurer"  class ="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
        
< property  name ="location"  value ="classpath:jdbc.properties" />
    
</ bean >
    
< bean  id ="_data_source"  class ="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        
< property  name ="driverClassName"  value ="${jdbc.driverClassName}" />
        
< property  name ="url"  value ="${jdbc.url}" />
        
< property  name ="username"  value ="${jdbc.username}" />
        
< property  name ="password"  value ="${jdbc.password}" />
    
</ bean >
    
< alias  name ="_data_source"  alias ="dataSource" />
    
< bean  id ="entityManagerFactory"  class ="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
        
< property  name ="persistenceUnitName"  value ="SpringJPADbUnit" />
        
< property  name ="dataSource"  ref ="dataSource" />
        
< property  name ="jpaVendorAdapter" >
            
< bean  class ="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
                
< property  name ="databasePlatform"  value ="${jdbc.dialect}" />
                
< property  name ="showSql"  value ="${jdbc.showSql}" />
                
< property  name ="generateDdl"  value ="${jdbc.generateDdl}" />
            
</ bean >
        
</ property >
    
</ bean >
    
< bean  id ="jDialect"  class ="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />  
    
< bean  id ="transactionManager"  class ="org.springframework.orm.jpa.JpaTransactionManager" >
        
< property  name ="entityManagerFactory"  ref ="entityManagerFactory" />
        
< property  name ="dataSource"  ref ="dataSource" />
        
< property  name ="jpaDialect"  ref ="jDialect" />
    
</ bean >
    
< tx:annotation-driven  transaction-manager ="transactionManager" />
</ beans >


<aop:aspectj-autoproxy/> 提供对AspectJ的支持
<context:annotation-config/> 提供对annotation的支持
<context:component-scan base-package="name.huliqing.magic"/> 指定需要被Spring进行扫描的类包,base-package下的类及子包都会被扫描以提供依赖注入,注意修改为自己的包名。
<tx:annotation-driven transaction-manager="transactionManager"/> 对Annotation进行事务管理的支持。
其它定义的一些bean主要是对数据源的配置,更详细的信息请查阅相关的资料。

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        
<property name="location" value="classpath:jdbc.properties"/>
</bean>
注意这里指定了数据源配置文件的位置classpath:jdbc.properties.

6.jdbc.properties

文件位置 classpath:jdbc.properties

jdbc.dialect  =  org.hibernate.dialect.MySQLDialect
jdbc.driverClassName 
=  com.mysql.jdbc.Driver
jdbc.url 
=  jdbc:mysql: // localhost:3306/magic?characterEncoding=UTF-8
jdbc.username  =  root
jdbc.password 
=
jdbc.showSql 
=   false
jdbc.generateDdl 
=   false


上面是jdbc文件的配置内容,下面显示了文件的位置,同时显示了Spring的两个配置文件的位置。


上面提供了对数据库的连接信息,数据库magic,用户root,密码空。基本上JSF+Spring+Hibernate+Facelets就是这个配置了。
下面为了测试环境,将在magic库中创建一个数据表test,并创建一些相应的类,进行测试一下。

7.测试环境

首先创建一个数据表magic.test

DROP   TABLE   IF   EXISTS  magic.test;

CREATE   database   IF   NOT   EXISTS  magic  DEFAULT  charset utf8 COLLATE utf8_general_ci;

use  magic;

create   table  magic.test (
    num 
int   not   null  auto_increment,
    id 
varchar ( 32 not   null ,
    password 
varchar ( 64 not   null ,
    des 
varchar ( 64 not   null ,
    
primary   key   (num)
) engine 
=  InnoDB  default  charset  =  utf8;


接下来将创建以下东东:
Dao.java - Dao接口:
DaoBase.java - Dao基类,实现Dao.java的接口

TestDa.java - Dao,继承DaoBase.java
TestEn.java - Entity,持久化类,对应数据表magic.test
TestSe.java - Service,业务逻辑层
TestWe.java - BackingBean
test.xhtml  - 测试页面

下面是目录结构,因为这是测试,所以我并没有把它们放在相应的目录。其它几个类可以不管。


下面是各个类的代码:
TestEn.java

package  name.huliqing.magic.test;

import  java.io.Serializable;
import  javax.persistence.Basic;
import  javax.persistence.Column;
import  javax.persistence.Entity;
import  javax.persistence.GeneratedValue;
import  javax.persistence.Id;
import  javax.persistence.NamedQueries;
import  javax.persistence.Table;

@Entity
@Table(name 
=   " test " )
@NamedQueries({})
public   class  TestEn  implements  Serializable {
    
private   static   final   long  serialVersionUID  =   1L ;
    @Id
    @GeneratedValue
    @Basic(optional 
=   false )
    @Column(name 
=   " num " )
    
private  Integer num;
    @Basic(optional 
=   false )
    @Column(name 
=   " id " )
    
private  String id;
    @Basic(optional 
=   false )
    @Column(name 
=   " password " )
    
private  String password;
    @Basic(optional 
=   false )
    @Column(name 
=   " des " )
    
private  String des;

    
public  TestEn() {
    }

    
public  TestEn(Integer num) {
        
this .num  =  num;
    }

    
public  TestEn(Integer num, String id, String password, String des) {
        
this .num  =  num;
        
this .id  =  id;
        
this .password  =  password;
        
this .des  =  des;
    }

    
public  Integer getNum() {
        
return  num;
    }

    
public   void  setNum(Integer num) {
        
this .num  =  num;
    }

    
public  String getId() {
        
return  id;
    }

    
public   void  setId(String id) {
        
this .id  =  id;
    }

    
public  String getPassword() {
        
return  password;
    }

    
public   void  setPassword(String password) {
        
this .password  =  password;
    }

    
public  String getDes() {
        
return  des;
    }

    
public   void  setDes(String des) {
        
this .des  =  des;
    }

    @Override
    
public   int  hashCode() {
        
int  hash  =   0 ;
        hash 
+=  (num  !=   null   ?  num.hashCode() :  0 );
        
return  hash;
    }

    @Override
    
public   boolean  equals(Object object) {
        
//  TODO: Warning - this method won't work in the case the id fields are not set
         if  ( ! (object  instanceof  TestEn)) {
            
return   false ;
        }
        TestEn other 
=  (TestEn) object;
        
if  (( this .num  ==   null   &&  other.num  !=   null ||  ( this .num  !=   null   &&   ! this .num.equals(other.num))) {
            
return   false ;
        }
        
return   true ;
    }

    @Override
    
public  String toString() {
        
return   " name.huliqing.magic.domain.TestEn[num= "   +  num  +   " ] " ;
    }

}

这个Entity是Netbeans通过数据表magic.test生成的代码,相关的注解都看到了,不明白的可以查阅一下相关资料

接口Dao.java

package  name.huliqing.magic.dao;

import  java.io.Serializable;

public   interface  Dao < T, PK  extends  Serializable > {

    
public  T save( final  T t);

    
public  T update( final  T t);

    
public   void  delete( final  T t);

    
public  T find( final  PK id);
}


基类:BaseDao.java

package  name.huliqing.magic.dao;

import  java.io.Serializable;
import  java.util.List;
import  javax.persistence.EntityManager;
import  javax.persistence.EntityManagerFactory;
import  javax.persistence.PersistenceUnit;
import  javax.persistence.Query;
import  org.springframework.beans.factory.annotation.Autowired;
import  org.springframework.jdbc.datasource.DriverManagerDataSource;
import  org.springframework.orm.jpa.JpaTemplate;

public   class  DaoBase < T, PK  extends  Serializable >   implements  Dao < T, PK > {

    
protected  Class < T >  type;
    
protected  JpaTemplate jpaTemplate;
    
protected  EntityManagerFactory entityManagerFactory;
    
protected  DriverManagerDataSource dateSource;

    
public  DaoBase(Class < T >  type) {
        
this .type  =  type;
    }

    @PersistenceUnit
    
public   void  setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        
this .entityManagerFactory  =  entityManagerFactory;
        
this .jpaTemplate  =   new  JpaTemplate(entityManagerFactory);
    }

    @Autowired
    
public   void  setDataSource(DriverManagerDataSource dateSource) {
        
this .dateSource  =  dateSource;
    }

    
public  T save(T t) {
        
this .jpaTemplate.persist(t);
        
this .jpaTemplate.flush();
        
return  t;
    }

    
public  T update(T t) {
        
this .jpaTemplate.merge(t);
        
this .jpaTemplate.flush();
        
return  t;
    }

    
public   void  delete(T t) {
        T _o 
=   this .jpaTemplate.merge(t);
        
this .jpaTemplate.remove(_o);
        
this .jpaTemplate.flush();
    }

    
public  T find(PK id) {
        
return  (T)  this .jpaTemplate.find(type, id);
    }

    
public  List < T >  findByObject(T t, String fuzzy) {
        EntityManagerFactory emf 
=   this .jpaTemplate.getEntityManagerFactory();
        EntityManager em 
=  emf.createEntityManager();
        Query q 
=  DaoQueryMake.makeQuery(em, t, fuzzy);
        List
< T >  result  =  q.getResultList();
        
return  result;
    }
}

Dao.java, DaoBase.java都使用了泛型,
Dao.java主要定义了相关的基本接口,
DaoBase.java主要提供了Spring对数据源的注入及管理,同时实现了Dao.java的接口,这样其它Dao只要继承自DaoBase.java就可以毫不费劲的获得几个很基本的功能:save, update, delete, find

测试类Dao: TestDa.java

package  name.huliqing.magic.test;

import  name.huliqing.magic.dao. * ;
import  org.springframework.stereotype.Component;

@Component
public   class  TestDa  extends  DaoBase{

    
public  TestDa() {
        
super (TestEn. class );
    }
}


测试类Service: TestSe.java

package name.huliqing.magic.test;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class TestSe {

    @Autowired
    private TestDa testDa;

    @Transactional
    public TestEn save(TestEn testEn) {
        return (TestEn) testDa.save(testEn);
    }

    @Transactional
    public TestEn update(TestEn testEn) {
        return (TestEn) testDa.update(testEn);
    }

    @Transactional
    public void delete(TestEn testEn) {
        testDa.delete(testEn);
    }

    public List<TestEn> findByObject(Object o, String... fuzzy) {
        return testDa.findByObject(o, fuzzy);
    }
}


测试类Backing: TestWe.java

package  name.huliqing.magic.test;

import  name.huliqing.magic.Message;
import  org.springframework.beans.factory.annotation.Autowired;
import  org.springframework.context.annotation.Scope;
import  org.springframework.stereotype.Component;

@Component
@Scope(
" request " )
public   class  TestWe  implements  java.io.Serializable{

    @Autowired
    
private  TestSe testSe;
    
private  TestEn testEn;

    
public  TestWe() {
        
this .testEn  =   new  TestEn();
    }

    
public  TestEn getTestEn() {
        
return  testEn;
    }

    
public   void  setTestEn(TestEn testEn) {
        
this .testEn  =  testEn;
    }

    
public   void  save() {
        TestEn _testEn 
=  testSe.save(testEn);
        
if  (_testEn  !=   null ) {
            Message.addInfoMessage(
" 注册成功 " );
        }
    }
}

看一下几个Test类,主要用到几个注解:@Component @Autowired @Transactional
@Component 标明了获得Spring管理的Bean, 默认名称为类名的首字母小写,主要注意Component的保存scope。
@Autowired 实现Bean的快速注入。
@Transactional,通过这个注解,方法将自动获得事务支持。

下面是测试页面:test.xhtml

 1  < ui:composition  xmlns ="http://www.w3.org/1999/xhtml"
 2          xmlns:h ="http://java.sun.com/jsf/html"
 3          xmlns:f ="http://java.sun.com/jsf/core"
 4          xmlns:t ="http://myfaces.apache.org/tomahawk"
 5          xmlns:ui ="http://java.sun.com/jsf/facelets"
 6          template ="/WEB-INF/layout/template.xhtml" >
 7       < ui:define  name ="content" >
 8           < ui:insert  name ="messages" >
 9               < h:messages  globalOnly ="true"  showDetail ="true"  infoClass ="colorGreen"  errorClass ="colorRed"  fatalClass ="colorOrange" />
10           </ ui:insert >
11           < h:form >
12           < h:panelGrid  columns ="3"  styleClass ="border" >
13               < h:outputText  value ="用户ID"   />
14               < h:inputText  id ="id"  value ="#{testWe.testEn.id}"   />
15               < h:outputText  value ="请填写你的ID"   />
16 
17               < h:outputText  value ="设置密码"   />
18               < h:inputSecret  id ="password"  value ="#{testWe.testEn.password}"   />
19               < h:outputText  value ="建议由字母与数字混合组成"   />
20 
21               < h:outputText  value ="个人说明"   />
22               < h:inputTextarea  id ="des"  value ="#{testWe.testEn.des}"   />
23               < h:outputText  value ="个人的一些备注"   />
24 
25               < h:panelGroup  />
26               < h:commandButton  value ="申请"  action ="#{testWe.save}"   />
27               < h:panelGroup  />
28           </ h:panelGrid >
29           </ h:form >
30       </ ui:define >
31  </ ui:composition >

关于Facelets视图技术,不明白的请查阅相关的资料,下面是最终测试结果。

以上整合配置有经过实际正式上线项目验证,如果你觉得有什么错漏,请多多指教。

1.示例源码下载,没带jar,需要自己去下载上面所说的相关jar包。(94K)
http://www.blogjava.net/Files/huliqing/Magic-JSH-Facelets-Annotation.rar

2.示例源码下载,完整版,包含所有相关jar,不过网盘可能不够稳定。(38M)
http://cid-1c243f9a849aade7.skydrive.live.com/self.aspx/.Public/Magic/Magic%7C5JSF+Spring+Hibernate+Facelets+Annotation%7C6.rar


huliqing
huliqing@live.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值