struts官方教程中有這麼一個例子,是Struts 2 + Spring 2 + JPA + AJAX 樣本,其源地址是:
http://struts.apache.org/2.3.1.1/docs/struts-2-spring-2-jpa-ajax.html
下載了例子後,手工匯入包來構建,我使用了2.3.1的包,構建中遇到很多問題。主要是包關係的問題,以及STRUTS更新後的一些改變。
做了以下一些改變:
1struts2.0的ajax支援主要以DWR和dojo為主,並專門提供ajax主題,如:<s:head theme="ajax"/>,但是在struts2.1不在提供ajax主題,而將原來的ajax主題放入了dojo外掛程式中,我們需要在工程中加個struts2-dojo-plugin.jar ,將dojo 標籤引入到jsp頁面
<%@ taglib uri="/struts-dojo-tags" prefix="sx" %>
2。把<s:head theme="ajax"/>改為
<s:head theme="xhtml" /><sx:head parseContent="true" />
3 將原有的一些<s: 換成<sx:, 可以根絕提示來換,有些是不能換的,按照ECLIPSE的提示即可。如果有報錯,可以掉裡面的theme="ajax"
4 驗證也調不通,於是去掉了驗證。
5 一切就緒,報錯:
FreeMarker template error!Expression parameters.pushId is undefined on line 24, column 6 in template/ajax/a-close.ftl.The problematic instruction:----------==> if parameters.pushId [on line 24, column 1 in template/ajax/a-close.ftl]
於是按照一個頁面的方法,做了如下操作:
The template problems you are having can be fixed by copying the template files into your local project (keeping the template/ajax directory structure) and changing the ftl so that they check for the existence of the parameter first i.e. change to: <#if
parameters.pushId?exists && parameters.pushId>.
就是找到了報錯的位置,複製了兩個檔案出來,並修改語句<#if parameters.pushId?exists && parameters.pushId>.
代碼與結構:
1使用MYSQL 資料庫
CREATE Database quickstart
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;
2 用了以下這些包
3 目錄結構
3 JAVA代碼如下:
Person.java
@Entity表示使用JPA實體。ID上面加入@Id說明這個是ID,@GeneratedValue自動產生ID值
package quickstart.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;@Entitypublic 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; }}
PersonService.java
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);}
PersonServiceImpl.java
@PersistenceContext標註使用JPA的上下文,設定實體管理器。@TransactionalIf
the class is annotated as @Transactional, Spring will make sure that its methods run inside a transaction.
package quickstart.service;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;@Transactionalpublic class PersonServiceImpl implements PersonService { private EntityManager em; @PersistenceContext public void setEntityManager(EntityManager em) { this.em = em; } @SuppressWarnings("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); }}
/PersonAction.java
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; }}
4 配置文檔
persistence.xml
<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>
struts.xml
<?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>
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: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="qwe123" /> </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>
web.xml
<?xml version="1.0" encoding="UTF-8"?><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>
5.頁面代碼
這裡使用的struts的AJAX,感覺不怎麼好用。不如使用EASYUI ,jquery,配合struts的json外掛程式來做會好點。
index.jsp
<%@ taglib prefix="s" uri="/struts-tags"%><%@ taglib uri="/struts-dojo-tags" prefix="sx" %><html><head><s:head theme="xhtml" /><sx:head parseContent="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;"> <sx:a notifyTopics="/refresh">Refresh</sx:a> </div> <sx: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" > <s:textfield id="id" name="person.id" cssStyle="display:none"/><s:textfield id="firstName" label="Fisrt Name" name="person.firstName"/><s:textfield id="lastName" label="Last Name" name="person.lastName"/><sx:submit targets="persons" notifyTopics="/save"/></s:form></div></body></html>
list.jsp
<%@ taglib prefix="s" uri="/struts-tags"%><%@ taglib uri="/struts-dojo-tags" prefix="sx" %><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><sx:a href="%{removeUrl}" targets="persons">Remove</sx:a><sx:a id="a_%{id}" notifyTopics="/edit">Edit</sx:a></td></tr></s:iterator></table></s:if>
最終結果如下:
程式碼封裝:
http://download.csdn.net/detail/magic_wz/3999729 已經打好了所需的各種包,可以ECLIPSE直接運行