Struts 2 + Spring 2 + JPA + AJAX 示例

 

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;

@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;

    }

}

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;


@Transactional
public 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直接运行

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

day walker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值