- 浏览: 1009688 次
文章分类
最新评论
-
18335864773:
很多公司项目 都在使用pageoffice 来操作word,e ...
用java生成word文档 -
Gozs_cs_dn:
请问下博主, 怎样将sitemesh3.xsd绑定 sitem ...
SiteMesh3配置 -
Rose_06:
springside4.0quick-start.bat报错原因 -
ilemma:
我也是刚参见工作啊,经理让自学这个,有些东西不太懂,能不能发个 ...
Apache Shiro在Web中的应用 -
shanbangyou:
你废了
程序员上班打酱油的方法
On this tutorial we will demonstrate how to setup Struts 2 in Eclipse, and make it work with Spring, Java Persistence API (using Hibernate) and Struts 2 Ajax tags.
NOTE: Following this tutorial verbatim will require use of a Struts 2 deployment greater than 2.0.3
divrequisites
Tomcat
Install Tomcat before going forward. See Tomcat's installation guide if you have any problem installing it.
MySql
Install and configure MySql. Create a database named "quickstart" and run the script below to create the "Person" table. Later, on applicationContext.xml, we'll use 'root' as the user name and password for the database, remember to replace those values with the right ones for your database.
'id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
'firstName' VARCHAR(45) NOT NULL,
'lastName' VARCHAR(45) NOT NULL,
PRIMARY KEY('id')
)
ENGINE = InnoDB;
Get the code
Show me the code
You can just download the zipped Eclipse project, add the required dependencies to the lib folder under the /WebContent/WEB-INF/lib folder (relative to project's root folder) and import it into Eclipse.
The maven way
To run the project this way you will need maven installed.
- Download the zipped project
- Download jta jar from here, and rename it to jta-1.0.1B.jar
- Install the jta jar file running:
$ mvn install:install-file -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B -Dpackaging=jar -Dfile=c:\path\to\jar\jta-1.0.1B.jar
- Bear with me, we are almost there
- cd into quickstart and run:
$ mvn jetty:run
- Point your browser to http://localhost:8080/quickstart
- To create an eclipse project run:
$ mvn eclipse:eclipse
Doing it yourself
Create Eclipse project
- Open Eclipse. Seriously, you need to open Eclipse.
- Click File -> New -> Project. Under the "Web" folder, select "Dynamic Web Project" and click "Next".
- Enter the project name, "quickstart" from here on. The project will be running inside Tomcat, so we need to create a server configuration for it.
- Under "Target Runtime", click "New", select "Apache Tomcat 5.5" and click next.
- Enter Tomcat's installation directory and select an installed JRE (1.5 is required)
- Now you should be back to the project creation wizard, with Tomcat as your Target Runtime. Click "Next". Select "Dynamic Web Module" and "Java" facets, and click "Finish".
Dependencies
Your project should contain the folders "src", "build" and "WebContent". We are going to put all the required jars under "/WebContent/WEB-INF/lib". To add files to the "lib" folder, just copy them to ${workspace}\quickstart\WebContent\WEB-INF\lib, where ${workspace} is the location of your Eclipse workspace folder. The version has been removed from the jar files.
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 |
Right click on the project and select "Refresh" (to notify Eclipse of the jars that we just added).
Domain
Our domain model will consist of just a simple "Person" class with a couple of fields.
- Create a new class named "Person" (File -> New -> Class), and enter "quickstart.model" for the package name.
- Add the fields "id" (int), "firstName" (String), and lastName ("String") with their setter/getter methods.
- Mark your class with the "@Entity" annotation, and the "id" field with the annotations "@Id" and "@GeneratedValue".
your class will look like:
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 will let the provider know that this class can be persisted. @Id marks the "id" field as the primary key for this class. @GeneratedValue will cause the id field to be generated by the provider (Hibernate). Classes and fields are by default mapped to tables and columns with the same name, see JPA's documentation for more details.
Person service.
We will now write the class that will take care of CRUD operations on "Person" objects.
- Create a new interface (File -> New -> Interface), enter "PersonService" for the name, and "quickstart.service" for the namespace. Set its content to:
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);
}
- Create a new class (File -> New -> Class), enter "PersonServiceImpl" for the name and "quickstart.service" for the namespace. Set its content to:
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.transaction.annotation.Transactional;
import quickstart.model.Person;
@Transactional
public class PersonServiceImpl implements PersonService {
private EntityManager em;
@PersistenceContext
public void setEntityManager(EntityManager em) {
this.em = em;
}
@SupdivssWarnings("unchecked")
public List<Person> findAll() {
Query query = getEntityManager().createQuery("select p FROM Person p");
return query.getResultList();
}
public void save(Person person) {
if (person.getId() == null) {
// new
em.persist(person);
} else {
// update
em.merge(person);
}
}
public void remove(int id) {
Person person = find(id);
if (person != null) {
em.remove(person);
}
}
private EntityManager getEntityManager() {
return em;
}
public Person find(int id) {
return em.find(Person.class, id);
}
}
@PersistenceContext will make Spring inject an EntityManager into the service when it is instantiated. The @PersistenceContext annotation can be placed on the field, or on the setter method. If the class is annotated as @Transactional, Spring will make sure that its methods run inside a transaction.
JPA configuration
- Create a folder named "META-INF" under the "src" folder.
- Create a file named "persistence.xml" under the "META-INF" folder and set its content to:
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.
Spring
- Update the content of web.xml under /WebContent/WEB-INF/web.xml to:
<web-app id="person" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>person</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
This will make the container redirect all requests to Struts "FilterDispatcher" class. "index.jsp" is set as the home page, and Spring's "ContextLoaderListener" is configured as a listener.
- Create a file named "applicationContext.xml" under /WebContent/WEB-INF, and set its content to:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="personService" class="quickstart.service.PersonServiceImpl" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/quickstart" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="personAction" scope="prototype"
class="quickstart.action.PersonAction">
<constructor-arg ref="personService" />
</bean>
</beans>
Note that the "class" attribute of the bean "personAction" is set to the name of the action class, and the "personService" bean will be passed as a parameter to the action constructor. Change the "url", "username" and "password" in the "dataSource" bean to the appropiate values for your database. For more details on the rest of the beans on this file, see Spring's documentation. The "scope" attribute is new in Spring 2, and it means that Spring will create a new PersonAction object every time an object of that type is requested. In Struts 2 a new action object is created to serve each request, that's why we need scope="prototype".
Struts
We will now create a simple Struts action that wraps PersonServices methods, and we will configure Struts to use Spring as the object factory.
- Open the new class dialog (File -> New -> Class) and enter "PersonAction" for the classname, and "quickstart.action" for the namespace. Set its content to:
import java.util.List;
import quickstart.model.Person;
import quickstart.service.PersonService;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.divparable;
public class PersonAction implements divparable {
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 divpare() throws Exception {
if (id != null)
person = service.find(id);
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
Look mom my action is a simple POJO!
The "divparable" interface instructs Struts to call the "divpare" method if the "divpareInterceptor" is applied to the action (by default, it is). The constructor of the action takes a "PersonService" as a parameter, which Spring will take care of passing when the action is instatiated.
- Create a new file named "struts.xml" under the "src" folder. And set its content to:
<!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>
Setting "struts.objectFactory" to "spring" will force Struts to instantiate the actions using Spring, injecting all the defined dependencies on applicationContext.xml. The "class" attribute for each action alias is set to "personAction", which is the bean id that we defined on applicationContext.xml for the PersonAction class. This is all that is needed to make Struts work with Spring.
The pages
We only have two pages, "index.jsp" and "list.jsp". "list.jsp" returns a table with a list of the persons on the database.We have this list on a different page because we are going to add some AJAX to spicy it up.
- Create a new file named "list.jsp" under /WebContent/pages/ and set its content to:
<p>Persons</p>
<s:if test="persons.size > 0">
<table>
<s:iterator value="persons">
<tr id="row_<s:property value="id"/>">
<td>
<s:property value="firstName" />
</td>
<td>
<s:property value="lastName" />
</td>
<td>
<s:url id="removeUrl" action="remove">
<s:param name="id" value="id" />
</s:url>
<s:a href="%{removeUrl}" theme="ajax" targets="persons">Remove</s:a>
<s:a id="a_%{id}" theme="ajax" notifyTopics="/edit">Edit</s:a>
</td>
</tr>
</s:iterator>
</table>
</s:if>
This is going to render a table with each row showing the first and last name of the person, a link to remove the person, and a link to edit. The remove link has the attribute "targets", set to "persons", which means that when the user clicks on it, an asynchronous request will be made to the "remove" action (as configured on struts.xml, "remove" points to the "remove" method in PersonAction), passing the person id as parameter.
When the edit link is clicked on, it will publish the "/edit" topic, which will trigger a javascript function to populate the fields.
- Create a new file named "index.jsp" under /WebContent and set its content to:
<html>
<head>
<s:head theme="ajax" debug="true"/>
<script type="text/javascript">
dojo.event.topic.subscribe("/save", function(data, type, request) {
if(type == "load") {
dojo.byId("id").value = "";
dojo.byId("firstName").value = "";
dojo.byId("lastName").value = "";
}
});
dojo.event.topic.subscribe("/edit", function(data, type, request) {
if(type == "before") {
var id = data.split("_")[1];
var tr = dojo.byId("row_"+id);
var tds = tr.getElementsByTagName("td");
dojo.byId("id").value = id;
dojo.byId("firstName").value = dojo.string.trim(dojo.dom.textContent(tds[0]));
dojo.byId("lastName").value = dojo.string.trim(dojo.dom.textContent(tds[1]));
}
});
</script>
</head>
<body>
<s:url action="list" id="descrsUrl"/>
<div style="width: 300px;border-style: solid">
<div style="text-align: right;">
<s:a theme="ajax" notifyTopics="/refresh">Refresh</s:a>
</div>
<s:div id="persons" theme="ajax" href="%{descrsUrl}" loadingText="Loading..." listenTopics="/refresh"/>
</div>
<br/>
<div style="width: 300px;border-style: solid">
<p>Person Data</p>
<s:form action="save" validate="true">
<s:textfield id="id" name="person.id" cssStyle="display:none"/>
<s:textfield id="firstName" label="First Name" name="person.firstName"/>
<s:textfield id="lastName" label="Last Name" name="person.lastName"/>
<s:submit theme="ajax" targets="persons" notifyTopics="/save"/>
</s:form>
</div>
</body>
</html>
Look mom no page refresh!
The div "persons" will load its content asynchronously, and will show "Loading..." while while the request is on progress (you can use the "indicator" attribute for better progress feedback), you can force it to refresh clicking on the "Refresh" link. The "submit" button, will make an asynchronous request to the action "save" ("save" method on PersonAction), and will publish the topic "/save" to which we subscribed to, using "dojo.event.topic.subscribe", to clear the input fields.
Validation
Because we don't want any John Doe on our database, we will add some basic client side validation to our form. In Struts 2, validation can be placed on xml files with the name pattern ActionName-validation.xml, located on the same package as the action. To add validation to an specific alias of an action (like a method), the validation file name follows the pattern ActionName-alias-validation.xml, where "alias" is the action alias name (in this case a method name, "save"). Add a file named "PersonAction-save-validation.xml" under /src/quickstart/action, and set its content to:
"-//OpenSymphony Group//XWork Validator 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="person.firstName">
<field-validator type="requiredstring">
<message>First name is required!</message>
</field-validator>
</field>
<field name="person.lastName">
<field-validator type="requiredstring">
<message>Last name is required!</message>
</field-validator>
</field>
</validators>
See the Struts documentation for details on existing validators, and how to write, and plug in, your own validators.
To run the project, Right click on your project and Run As -> Run on Server. You can debug it on the same way, Right click on the project and Debug As -> Debug on Server. Download and install Struts 2 Showcase to see more examples.
Using Toplink Essentials instead of Hibernate
- Add this to pom.xml
<repositories>
<repository>
<id>java.net</id>
<url>https://maven-repository.dev.java.net/nonav/repository</url>
<layout>legacy</layout>
</repository>
</repositories> - Add this to the dependencies node in pom.xml
<dependency>
<groupId>toplink.essentials</groupId>
<artifactId>toplink-essentials</artifactId>
<version>2.0-38</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency> - Replace the jpaVendorAdapter element in applicationContext.xml with this:
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
<property name="databasePlatform" value="oracle.toplink.essentials.platform.database.MySQL4Platform" />
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
</bean>
</property>
References
StrutsSpring JPA Doc
JPA and Spring Tutorial
Eclipse Dali
相关推荐
Struts2、Spring2、JPA(Java Persistence API)和Ajax是Java Web开发中的四大关键技术,它们共同构建了一个高效、灵活且功能强大的应用程序框架。在这个项目中,这四者的组合运用旨在实现一个前后端分离、数据持久...
### Struts 2 + Spring 2 + JPA + AJAX 技术栈详解 #### 一、技术背景与介绍 在企业级应用开发中,选择合适的技术栈是非常重要的一步。Struts 2 + Spring 2 + JPA + AJAX 这个组合是早期非常流行的一个Java Web...
Struts 2、Spring 2、JPA 和 AJAX 是企业级 Web 应用开发中的四大核心技术,它们在构建高效、可扩展的系统中扮演着重要角色。本示例结合这四种技术,提供了一个完整的应用实例,帮助开发者了解如何将它们整合在一起...
**整合 Struts 2 + Spring 2 + JPA + AJAX** 在现代Web应用程序开发中,Struts 2、Spring、JPA 和 AJAX 是四个非常重要的技术组件。它们各自扮演着关键角色,共同构建了一个功能强大且灵活的后端架构。 **Struts 2...
Struts2+Spring 2+JPA+AJAX学习项目是一个经典的Java Web开发组合,用于构建高效、可扩展的应用程序。这个项目的核心组件包括: 1. **Struts2**: Struts2是一个基于MVC(Model-View-Controller)设计模式的Java Web...
在本文中,我们将深入探讨如何使用Eclipse进行Java企业级应用开发,具体涉及Struts 2、Spring 2、JPA以及AJAX技术的集成。这些框架和技术的结合提供了强大的功能,包括MVC架构、依赖注入、持久化管理和异步通信。 ...
Struts 2、Spring 2 和 JPA 是Java Web开发中的三个重要框架,它们共同构建了一个强大、灵活的后端架构。在这个示例中,它们与AJAX技术结合,提供了更丰富的用户交互体验。让我们详细了解一下这些技术以及它们如何...
标题 "ssh2(struts2+spring2.5+hibernate3.3+ajax)带进度条文件上传(封装成标签)" 涉及到的是一个基于Java Web的项目,利用了Struts2、Spring2.5、Hibernate3.3和Ajax技术,实现了文件上传并带有进度条显示的功能...
该项目是一个基于Struts2、Spring、JPA和Ajax技术实现的网上购物系统。这个系统的主要目的是为了演示如何在实际开发中整合这些技术,提供一个功能完善的电商应用框架。以下是对这些关键技术点的详细解释: **Struts...
### Struts2、AJAX、JPA与Spring的综合运用 在IT领域,尤其是在Web开发中,集成多种框架和技术以创建高效、可扩展且功能丰富的应用程序是常见的实践。本篇文章将深入探讨Struts2、AJAX、JPA与Spring这四种技术的...
Struts2、Spring和Hibernate是Java Web开发中的三大框架,它们的整合(SSH)极大地提升了开发效率和项目的可维护性。下面将详细讲解这三大框架的核心功能以及整合过程中的关键知识点。 1. **Struts2**:Struts2是一...
Struts2、Spring2.5、JPA(Hibernate)以及AJAX是构建高效、模块化且可维护的企业级Web应用程序的常用技术栈。这个实例项目整合了这些技术,旨在提供一个全面的开发环境,帮助开发者理解和掌握它们的协同工作方式。 ...
Struts2、Spring3和Hibernate4是Java Web开发中的三大框架,它们的整合是构建高效、灵活的企业级应用的常用方式。这篇详细的知识点解析将深入探讨这三个框架的各自功能,以及如何将它们有效地整合在一起。 **Struts...