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

JSF+Spring+Hibernate+Facelets整合实践
本文提供了一个整合JSF、Spring、Hibernate、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文件配置

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 <? xmlversion="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/javaeehttp://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 > FacesServlet </ 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 > FacesServlet </ 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 > FacesServlet </ 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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 <? xmlversion='1.0'encoding='UTF-8' ?>
2
3 <!-- ===========FULLCONFIGURATIONFILE================================== -->
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/javaeehttp://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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> <? xmlversion="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/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/txhttp://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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> <? xmlversion="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-scanbase-package="name.huliqing.magic"/> 指定需要被Spring进行扫描的类包,base-package下的类及子包都会被扫描以提供依赖注入,注意修改为自己的包名。
<tx:annotation-driventransaction-manager="transactionManager"/> 对Annotation进行事务管理的支持。
其它定义的一些bean主要是对数据源的配置,更详细的信息请查阅相关的资料。

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

6.jdbc.properties

文件位置 classpath:jdbc.properties

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> DROP TABLE IF EXISTS magic.test;

CREATE database IF NOT EXISTS magic DEFAULT charsetutf8COLLATEutf8_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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 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 Integernum;
@Basic(optional
= false )
@Column(name
= " id " )
private Stringid;
@Basic(optional
= false )
@Column(name
= " password " )
private Stringpassword;
@Basic(optional
= false )
@Column(name
= " des " )
private Stringdes;

public TestEn(){
}

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

public TestEn(Integernum,Stringid,Stringpassword,Stringdes){
this .num = num;
this .id = id;
this .password = password;
this .des = des;
}

public IntegergetNum(){
return num;
}

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

public StringgetId(){
return id;
}

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

public StringgetPassword(){
return password;
}

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

public StringgetDes(){
return des;
}

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

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

@Override
public boolean equals(Objectobject){
// TODO:Warning-thismethodwon'tworkinthecasetheidfieldsarenotset
if ( ! (object instanceof TestEn)){
return false ;
}
TestEnother
= (TestEn)object;
if (( this .num == null && other.num != null ) || ( this .num != null && ! this .num.equals(other.num))){
return false ;
}
return true ;
}

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

}

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

接口Dao.java

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> package name.huliqing.magic.dao;

import java.io.Serializable;

public interface Dao < T,PK extends Serializable > {

public Tsave( final Tt);

public Tupdate( final Tt);

public void delete( final Tt);

public Tfind( final PKid);
}


基类:BaseDao.java

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 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 JpaTemplatejpaTemplate;
protected EntityManagerFactoryentityManagerFactory;
protected DriverManagerDataSourcedateSource;

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

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

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

public Tsave(Tt){
this .jpaTemplate.persist(t);
this .jpaTemplate.flush();
return t;
}

public Tupdate(Tt){
this .jpaTemplate.merge(t);
this .jpaTemplate.flush();
return t;
}

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

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

public List < T > findByObject(Tt,Stringfuzzy){
EntityManagerFactoryemf
= this .jpaTemplate.getEntityManagerFactory();
EntityManagerem
= emf.createEntityManager();
Queryq
= 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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 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 TestSetestSe;
private TestEntestEn;

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

public TestEngetTestEn(){
return testEn;
}

public void setTestEn(TestEntestEn){
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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值