本文翻译自:http://cwiki.apache.org/S2WIKI/struts-2-spring-2-jpa-ajax.html
我今天下午调试成功的, 昨天调试了一天, 都没有成功, 不是contextLoadListener找不到就是 server start error. 今天调试成功发现原来是人品问题, 是选择hibernate 包的时候没有注意hibernate compatable matrix
Package | Version | Core | Annotations | EntityManager | Validator | Search | Shards | Tools |
Hibernate Core | 3.2.2 GA | - | 3.2.x, 3.3.x | 3.2.x, 3.3.x | 3.0.x | 3.0.x | 3.0.x | 3.2.0 Beta9 |
Hibernate Annotations | 3.3.0 GA | 3.2.x | - | 3.3.x | 3.0.x | 3.0.x | Not compatible | 3.2.0 Beta9 |
Hibernate EntityManager | 3.3.1 GA | 3.2.x | 3.3.0.GA | - | 3.0.x | 3.0.x | Not compatible | 3.2.0 Beta9 |
Hibernate Validator | 3.0.0 GA | 3.2.x | 3.3.x | 3.3.x | - | 3.0.x | 3.0.x | 3.2.0 Beta9 |
Hibernate Search | 3.0.0 Beta4 | >= 3.2.2 | 3.3.x | 3.3.x | 3.0.x | - | 3.0.x | Not compatible |
Hibernate Shards | 3.0.0 Beta2 | 3.2.x | 3.3.x | Not compatible | 3.0.x | 3.0.x | - | - |
Hibernate Tools | 3.2.0 Beta9 | 3.2.x | 3.2.x and 3.3.x | 3.2.x and 3.3.x | 3.0.x | Not compatible | - | - |
在你开始加包的时候无比要仔细阅读 上面的矩阵, hiberante core 3.3 和有的包是不兼容的!
昨天试了 spring 2.0 + hibernate core 3.3 + struts2..0.9 没有成功,
今天调试成功的 版本为 struts2.0.9+spring2.0+hibernate 3.2.1 + tomcat5.5.17+ eclipse3.2 wtp all in one
本指南演示了如何在Eclipse中配置Struts2,并让它与Spring2,Java Persistence API(使用Hibernate)和Struts2 Ajax 标签一起工作。
注意:按指南一步一步来需要Struts2.0.3或更高版本
你可以在 zipped Eclipse project下载源代码,必需的依赖库在/WebContent/WEB-INF/lib目录下,需要导入到Eclipse中。
首先要安装好Tomcat,如果在安装的时候遇到任何问题,请查看Tomcat的安装指南
安装并配置MySQL。创建一个名为“quickstart”的数据库,并运行下面脚本来创建“Person”表。后面在applicationContext.xml里,我们将使用"root"数据库用户名和密码,记得用你自己的数据库设置来替换它们。
CREATE
TABLE
'
quickstart
'
.
'
Person
'
(
'
id
'
INTEGER
UNSIGNED
NOT
NULL
AUTO_INCREMENT,
'
firstName
'
VARCHAR
(
45
)
NOT
NULL
,
'
lastName
'
VARCHAR
(
45
)
NOT
NULL
,
PRIMARY
KEY
(
'
id
'
)
)
ENGINE
=
InnoDB;
注:上面的DDL需要保存在文件中,然后在MySQL中导入。我直接复制然后在查询分析器中执行失败
(上面讲的都是Eclipse WTP中的配置,如果使用MyEclipse请自行修正)
你的项目应该包含"src","build"和"WebContent"目录。我们把所有必需的jar文件放在"/WebContent/WEB-INF/lib"目录下。请复制它们到${workspace}/quickstart/WebContent/WEB-INF/lib目录。jar文件名的版本号已经被去除了!
Jar | From |
---|---|
xwork.jar | Struts 2 |
struts2-api.jar | Struts 2 |
struts2-core.jar | Struts 2 |
struts2-Spring-plugin.jar | Struts 2 |
ognl.jar | Struts 2 |
freemarker-2.3.4.jar | Struts 2 |
mysql-connector-java.jar | MySql JDBC Driver |
spring.jar | Sping 2.0 |
antlr.jar | Hibernate Core |
asm.jar | Hibernate Core |
asm-attrs.jar | Hibernate Core |
cglib.jar | Hibernate Core |
dom4j.jar | Hibernate Core |
jdbc2_0-stdext.jar | Hibernate Core |
ehcache.jar | Hibernate Core |
hibernate3.jar | Hibernate Core |
xml-apis.jar | Hibernate Core |
commons-collections.jar | Hibernate Core |
ejb3-persistence.jar | Hibernate Annotations |
jta.jar | Hibernate Annotations |
hibernate-annotations.jar | Hibernate Annotations |
hibernate-entitymanager.jar | Hibernate Entity Manager |
javassist.jar | Hibernate Entity Manager |
jboss-archive-browsing.jar | Hibernate Entity Manager |
右击项目点“刷新”,通知Eclipse我们加入了很多的jar文件。
我使用Struts2.0.9, Spring2.0., Hibernate3.2.1。struts2-api.jar找不到,没有也可以运行成功;Hibernate Annotations和Hibernate Entity Manager需要在Hibernate的主页上下载,不包括在Core里面;
本网站上还有一位仁兄给出了如下 评语:
jta.jar和javassist.jar在Hibernate Tools里面,同样要下载;最后,上面列表并缺少一个包,因为Hibernate3.2对此有一点小小的修改,你需要把Hibernate Annotations里面的hibernate-commons-annotations.jar拷贝进来。
其实 jta.jar和javassist.jar 在 annotation and Entity manager 里有了, 不用tool 包, 还有没有hibernate-commons-annotations.jar 一样可以跑
要注意的是下面的所有xml 第一行要加 , 在官方网站上的原文未来简洁省略了这句话, 一定要加上去
我们的领域模型只有一个简单的"Person"类,它包含少量的实例变量。
你的类如下:
package
quickstart.model;
import
javax.persistence.Entity;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Id;
@Entity
public
class
Person {
@Id
@GeneratedValue
private
Integer id;
private
String lastName;
private
String firstName;
public
String getFirstName() {
return
firstName;
}
public
void
setFirstName(String firstName) {
this
.firstName
=
firstName;
}
public
String getLastName() {
return
lastName;
}
public
void
setLastName(String lastName) {
this
.lastName
=
lastName;
}
public
Integer getId() {
return
id;
}
public
void
setId(Integer id) {
this
.id
=
id;
}
}
@Entity让JPA服务Provider知道这个类可以被持久化。@Id标识"id"域为这个类的主键,@GeneratedValue使id域被提供者(Hibernate)自动生成。类和实例变量默认都被映射到同名的表和列上,详细情况请查看JPA文档。
我们现在来写对"Person"对象进行CRUD操作的类。
package
quickstart.service;
import
java.util.List;
import
quickstart.model.Person;
public
interface
PersonService {
public
List
<
Person
>
findAll();
public
void
save(Person person);
public
void
remove(
int
id);
public
Person find(
int
id);
}
2. 创建一个类,命名为"PersonServiceImpl",包名为"quickstart.service"
<
persistence
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_1_0.xsd"
version
="1.0"
>
<
persistence-unit
name
="punit"
>
persistence-unit
>
persistence
>
JPA configuration can be set on this file. On this example it will be empty because the datasource configuration will be on the Spring configuration file. JPA的配置信息可以在这个文件中设置。本例中该文件为空,因为数据源(datasource)配置放在Spring的配置文件中。
现在我们需要创建一个简单的Struts action,它封装了PersonServices的方法。并且我们配置Struts使用Spring作为对象工厂。
package
quickstart.action;
import
java.util.List;
import
quickstart.model.Person;
import
quickstart.service.PersonService;
import
com.opensymphony.xwork2.Action;
import
com.opensymphony.xwork2.Preparable;
public
class
PersonAction
implements
Preparable {
private
PersonService service;
private
List
<
Person
>
persons;
private
Person person;
private
Integer id;
public
PersonAction(PersonService service) {
this
.service
=
service;
}
public
String execute() {
this
.persons
=
service.findAll();
return
Action.SUCCESS;
}
public
String save() {
this
.service.save(person);
this
.person
=
new
Person();
return
execute();
}
public
String remove() {
service.remove(id);
return
execute();
}
public
List
<
Person
>
getPersons() {
return
persons;
}
public
Integer getId() {
return
id;
}
public
void
setId(Integer id) {
this
.id
=
id;
}
public
void
prepare()
throws
Exception {
if
(id
!=
null
)
person
=
service.find(id);
}
public
Person getPerson() {
return
person;
}
public
void
setPerson(Person person) {
this
.person
=
person;
}
}
看,我的action是一个简单的POJO!
"Preparable"接口指示Struts去调用"prepare"方法,如果"PrepareInterceptor"被应用在action上(默认就是这样子的)。action的构造器有一个"PersonService"参数,在action被实例化的时候Spring会负责注入。
xml version="1.0" encoding="UTF-8"
?>
DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd"
>
<
struts
>
<
constant
name
="struts.objectFactory"
value
="spring"
/>
<
constant
name
="struts.devMode"
value
="true"
/>
<
package
name
="person"
extends
="struts-default"
>
<
action
name
="list"
method
="execute"
class
="personAction"
>
<
result
>
pages/list.jsp
result
>
<
result
name
="input"
>
pages/list.jsp
result
>
action
>
<
action
name
="remove"
class
="personAction"
method
="remove"
>
<
result
>
pages/list.jsp
result
>
<
result
name
="input"
>
pages/list.jsp
result
>
action
>
<
action
name
="save"
class
="personAction"
method
="save"
>
<
result
>
pages/list.jsp
result
>
<
result
name
="input"
>
pages/list.jsp
result
>
action
>
package
>
struts
>
设置"struts.objectFactory"为"spring"会强制Struts使用Spring来实例化action,并注入所有定义在applicationContext.xml中的依赖关系。每个action别名的"class"属性被设置为"personAction",这也就是我们在applicationContext.xml中定义的PersonAction bean。要让Struts与Spring一起工作,我们仅仅需要做上面这点事情。
我们只有两个页面,"index.jsp"和"list.jsp"。"list.jsp"返回数据库中所有person的列表。我们把这个列表放到一个不同的页面上,是因为我们将要添加一点ajax来改进它。
当编辑链接被点击时,它会打开/edit主题,这将触发一个javascript函数来组装各个域。
看,并没有页面刷新!
"personx" div会异步地装载它的内容,当请求被处理时显示"Loading..."提示(你可以使用"indicator"属性得到更佳的进度反馈),你可以通过点击"Refresh"链接来强制页面进行刷新。"submit"按钮,向action "save"提交一个异步的请求(PersonAction的"save"方法)
我们并不想我们的数据库存在任何的无名氏,所以我们给Form增加一点基本的客户端验证。在Struts2中,验证可以被放在xml文件里,命名模式为:ActionName-validation.xml,放在与action相同的包路径下。要给action的特定别名添加验证(比如方法),validation文件的命名必须为:ActionName-alias-validation.xml,这里的"alias"就是你的action的别名(这里也就是方法名,如"save")。在src/quickstart/action目录下添加一个名为"PersonAction-save-validation.xml"文件,它的内容如下:
关于现有的validator,以及如何编写和插入你自己的validator,请查看Struts文档
要运行项目,右击你的项目并选择Run AS -> Run on Server。你也可以通过相同的办法来调试它,右击项目 Debug As -> Debug on Server。下载并安装Struts 2的 showcase演示项目来查看更多的例子。