Struts 2.0,hibernate和spring的框架整合。
使用SSH框架和MySQL数据库。实现Spring对Hibernate和Struts的整合。
主要分为三大步骤:
1.Spring对Hibernate和Struts整合的环境搭建;
2.实现Spring对Hibernate和Struts的整合;
3.简单操作数据库,增、删、改、查和分页功能。
详细的项目整合过程可以参考本人的GitHub资源 https://github.com/PrimarySS/SSH
Spring对Hibernate和Struts整合的环境搭建
jar包
src下的db.properties 数据源信息:不再需要在hibernate.cfg.xml下配置数据源,hibernate与spring整合后交给spring.xml配置
src下的log4j.properties日志文件:记录出现的错误信息,便于找到问题所在
实现Spring对Hibernate和Struts的整合并简单操作数据库,增、删、改、查功能。
代码逻辑实现
创建实体类: ShippingAddress.java
package cn.hnck.com.entity;
/**
*
* @ClassName: ShippingAddress
* @Description: 新增收货地址
* @author XHChen
* @date 2018-9-19 下午10:34:38
*
*/
public class ShippingAddress {
private int id; // 地址id
private String recipient; // 收件人
private String mobilePhone; // 手机号
private String address; // 收货地址(省/市/县(区))
private String detailedAddress; // 详细地址
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRecipient() {
return recipient;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
public String getMobilePhone() {
return mobilePhone;
}
public void setMobilePhone(String mobilePhone) {
this.mobilePhone = mobilePhone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDetailedAddress() {
return detailedAddress;
}
public void setDetailedAddress(String detailedAddress) {
this.detailedAddress = detailedAddress;
}
}
配置ShippingAddress.java实体类: ShippingAddress.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.hnck.com.entity">
<!-- 配置类和表对应 class标签 name属性:实体类的全路径 table属性:数据库表的名称 -->
<class name="cn.hnck.com.entity.ShippingAddress" table="address">
<!-- 配置表id和实体类id对应 hibernate要求实体类有唯一的属性 hibernate要求表有唯一字段 -->
<!-- id标签 name:实体类的属性 column:表的子段名称 -->
<id name="id" column="id">
<!--设置数据表id增长策略 native:自动生成id为主键 -->
<generator class="native"></generator>
</id>
<!-- 配置实体类其他属性 proprety标签 name:实体类的属性 column:表的子段名称 -->
<property name="recipient" column="recipient"></property>
<property name="mobilePhone" column="mobilePhone"></property>
<property name="address" column="address"></property>
<property name="detailedAddress" column="detailedAddress"></property>
</class>
</hibernate-mapping>
创建dao接口: AddressDao.java
package cn.hnck.com.dao;
import java.util.List;
import cn.hnck.com.entity.ShippingAddress;
/**
*
* @ClassName: AddressDao
* @Description: 数据层接口,给serviceImpl调用,传入数据
* @author XHChen
* @date 2018-9-21 下午3:46:52
*
*/
public interface AddressDao {
// 添加地址
public int AddAddress(ShippingAddress address) throws Exception;
// 更新地址
public int UpdateAddress(ShippingAddress address) throws Exception;
// 删除地址
public int DeleteAddress(int id) throws Exception;
// 根据id查询地址
public ShippingAddress FindAddressById(int addressID) throws Exception;
// 查询所有地址
public List<ShippingAddress> FindAllAddress(String entityName) throws Exception;
// 获得数据库信息总数
public int realPage(String entityName);
// 分页
public List<ShippingAddress> getByPage(String entityName, int pageNo, int pageSize, int real);
}
实现dao接口: AddressDaoImpl.java
package cn.hnck.com.dao.impl;
import java.util.List;
import org.springframework.orm.hibernate3.HibernateTemplate;
import cn.hnck.com.dao.AddressDao;
import cn.hnck.com.entity.ShippingAddress;
public class AddressDaoImpl implements AddressDao {
private HibernateTemplate hibernateTemplate;
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
@Override
/**
* 添加地址
*/
public int AddAddress(ShippingAddress address) throws Exception {
// 保存dao接口传过来的封装数据
try {
this.hibernateTemplate.saveOrUpdate(address);
return 1;
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getStackTrace());
}
return 0;
}
@Override
/**
* 更新地址
*/
public int UpdateAddress(ShippingAddress address) throws Exception {
// 保存更新的数据
try {
this.hibernateTemplate.saveOrUpdate(address);
return 1;
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getStackTrace());
}
return 0;
}
@Override
/**
* 删除地址
*/
public int DeleteAddress(int id) throws Exception {
// 根据id删除数据
try {
// 根据id找到对象
ShippingAddress as = hibernateTemplate.get(ShippingAddress.class,id);
// 删除对象
hibernateTemplate.delete(as);
return 1;
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getStackTrace());
}
return 0;
}
@Override
/**
* 根据id查询地址
*/
public ShippingAddress FindAddressById(int addressID) throws Exception {
return this.hibernateTemplate.get(ShippingAddress.class, addressID);
}
@SuppressWarnings("unchecked")
@Override
/**
* 查询地址
*/
public List<ShippingAddress> FindAllAddress(String entityName)
throws Exception {
return (List<ShippingAddress>) this.hibernateTemplate.find("from" + " "+ entityName);
}
@Override
/**
* 获得数据库信息总数
*/
public int realPage(String entityName) {
return this.hibernateTemplate.find("from" + " " + entityName).size();
}
@SuppressWarnings("unchecked")
@Override
/**
* 分页
*/
public List<ShippingAddress> getByPage(String entityName, int pageNo, int pageSize, int real) {
int begin = (pageNo - 1) * pageSize;
int end = (pageNo) * pageSize;
// bug修改显示bug
if (end > real) {
end = real;
}
return (List<ShippingAddress>) this.hibernateTemplate.find("from" + " " + entityName).subList(begin, end);
}
}
创建service接口:AddressService.java
package cn.hnck.com.service;
import java.util.List;
import cn.hnck.com.entity.ShippingAddress;
/**
*
* @ClassName: AddressService
* @Description: dao的service处理,给Action调用,传入数据
* @author XHChen
* @date 2018-9-21 下午4:04:00
*
*/
public interface AddressService {
// 添加地址
public boolean AddAddress(ShippingAddress address) throws Exception;
// 更新地址
public boolean UpdateAddress(ShippingAddress address) throws Exception;
// 删除地址
public boolean DeleteAddress(int id) throws Exception;
// 根据id查询地址
public ShippingAddress FindAddressById(int addressID) throws Exception;
// 查询所有地址
public List<ShippingAddress> FindAllAddress() throws Exception;
// 获得数据库总数
public int maxSize() throws Exception;
// 分页
public List<ShippingAddress> getByPage(int pageNo, int pageSize);
}
实现service接口:AddressServiceImpl.java
package cn.hnck.com.service.impl;
import java.util.List;
import cn.hnck.com.dao.AddressDao;
import cn.hnck.com.entity.ShippingAddress;
import cn.hnck.com.service.AddressService;
public class AddressServiceImpl implements AddressService {
// 导入dao接口对象
private AddressDao addressDao;
public void setAddressDao(AddressDao addressDao) {
this.addressDao = addressDao;
}
@Override
/**
* 添加地址
*/
public boolean AddAddress(ShippingAddress address) throws Exception {
int flag = this.addressDao.AddAddress(address);
if (flag == 1) {
return true;
} else {
return false;
}
}
@Override
/**
* 更新地址
*/
public boolean UpdateAddress(ShippingAddress address) throws Exception {
int flag = this.addressDao.UpdateAddress(address);
if (flag == 1) {
return true;
} else {
return false;
}
}
@Override
/**
* 删除地址
*/
public boolean DeleteAddress(int id) throws Exception {
int flag = this.addressDao.DeleteAddress(id);
if (flag == 1) {
return true;
} else {
return false;
}
}
@Override
/**
* 根据id查询地址
*/
public ShippingAddress FindAddressById(int addressID) throws Exception {
return this.addressDao.FindAddressById(addressID);
}
@Override
/**
* 查询地址
*/
public List<ShippingAddress> FindAllAddress() throws Exception {
return addressDao.FindAllAddress("ShippingAddress");
}
@Override
/**
* 获得数据库信息总数
*/
public int maxSize() throws Exception {
int count = 0;
int maxPage = 0;
count = this.addressDao.realPage("ShippingAddress");
maxPage = (count + 4) / 5;
return maxPage;
}
@Override
/**
* 分页
*/
public List<ShippingAddress> getByPage(int pageNo, int pageSize) {
int real = this.addressDao.realPage("ShippingAddress");
return this.addressDao.getByPage("ShippingAddress", pageNo, pageSize, real);
}
}
创建action:ShippingAddressAction.java,模型驱动封装页面数据
package cn.hnck.com.action;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import cn.hnck.com.dto.ShippingAddressDTO;
import cn.hnck.com.entity.ShippingAddress;
import cn.hnck.com.service.AddressService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
/**
*
* @ClassName: ShippingAddressAction
* @Description: 模型驱动,获得页面数据,调用service接口的方法,传入数据
* @author XHChen
* @date 2018-9-21 下午4:42:17
*
*/
public class ShippingAddressAction extends ActionSupport implements
ModelDriven<ShippingAddressDTO> {
private static final long serialVersionUID = 1L;
// 单例模式
private ShippingAddressDTO AddressDTO = new ShippingAddressDTO();
private ShippingAddress address;
// service ioc
private AddressService addressService;
public void setAddressService(AddressService addressService) {
this.addressService = addressService;
}
private List<ShippingAddress> list;
// 修改
private ShippingAddress updateAddress;
// 请求,响应页面
private HttpServletRequest request;
private HttpServletResponse response;
// 分页
private int page;
private int maxPage;
// 增加
public String save() throws Exception {
address = new ShippingAddress();
address.setRecipient(AddressDTO.getRecipient());
address.setMobilePhone(AddressDTO.getMobilePhone());
address.setAddress(AddressDTO.getAddress());
address.setDetailedAddress(AddressDTO.getDetailedAddress());
this.addressService.AddAddress(address);
return "find";
}
// 修改
public String update() throws Exception {
updateAddress = new ShippingAddress();
updateAddress.setId(AddressDTO.getId());
updateAddress.setRecipient(AddressDTO.getRecipient());
updateAddress.setMobilePhone(AddressDTO.getMobilePhone());
updateAddress.setAddress(AddressDTO.getAddress());
updateAddress.setDetailedAddress(AddressDTO.getDetailedAddress());
this.addressService.UpdateAddress(updateAddress);
return "find";
}
// 删除
public String delete() throws Exception {
this.addressService.DeleteAddress(AddressDTO.getId());
return "find";
}
// 查询
public String show() throws Exception {
// 返回数据库所有信息
list = this.addressService.FindAllAddress();
// 把返回的实体setAttribute到页面
ActionContext.getContext().put("list", list);
return "list";
}
// 分页显示
public String list() throws Exception {
this.request = ServletActionContext.getRequest();
int maxPage = this.addressService.maxSize();
int pageNo = 1;
int pageSize = 5;
if (page > 0) {
pageNo = page;
}
list = this.addressService.getByPage(pageNo, pageSize);
// 把返回的实体setAttribute到页面
ActionContext.getContext().put("list", list);
request.setAttribute("page", pageNo);
request.setAttribute("maxPage", maxPage);
return "list";
}
// 预修改
public String FindAddressById() throws Exception {
// 根据id查询,返回实体
updateAddress = this.addressService.FindAddressById(AddressDTO.getId());
// 把返回的实体setAttribute到页面
ActionContext.getContext().put("updateAddress", updateAddress);
return "update";
}
@Override
public ShippingAddressDTO getModel() {
return AddressDTO;
}
public List<ShippingAddress> getList() {
return list;
}
public void setList(List<ShippingAddress> list) {
this.list = list;
}
public ShippingAddress getUpdateAddress() {
return updateAddress;
}
public void setUpdateAddress(ShippingAddress updateAddress) {
this.updateAddress = updateAddress;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getMaxPage() {
return maxPage;
}
public void setMaxPage(int maxPage) {
this.maxPage = maxPage;
}
}
因为本列中用了模型驱动封装页面数据的方法,所以需要创建实体类ShippingAddress.java的副本:ShippingAddressDTO.java
package cn.hnck.com.dto;
/**
*
* @ClassName: ShippingAddressDTO
* @Description: 用于模型驱动封装
* @author XHChen
* @date 2018-9-26 下午1:28:10
*
*/
public class ShippingAddressDTO {
private int id; // 地址id
private String recipient; // 收件人
private String mobilePhone; // 手机号
private String address; // 收货地址(省/市/县(区))
private String detailedAddress; // 详细地址
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRecipient() {
return recipient;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
public String getMobilePhone() {
return mobilePhone;
}
public void setMobilePhone(String mobilePhone) {
this.mobilePhone = mobilePhone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDetailedAddress() {
return detailedAddress;
}
public void setDetailedAddress(String detailedAddress) {
this.detailedAddress = detailedAddress;
}
@Override
public String toString() {
return "ShippingAddress [id=" + id + ", recipient=" + recipient
+ ", mobilePhone=" + mobilePhone + ", address=" + address
+ ", detailedAddress=" + detailedAddress + "]";
}
}
配置文件
web.xml: 注意配置监听器ContextLoaderListener,监听指定文件和配置struts2需要的过滤器StrutsPrepareAndExecuteFilter
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_ID">
<display-name>UNStore</display-name>
<!-- 配置监听器加载spring配置文件 -->
<!-- 配置监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 监听指定文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!-- 配置过滤器加载struts配置文件 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
struts.xml: 必须注意action里的name和result里的name
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 设置编码方式 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<package name="defualt" extends="struts-default" namespace="/">
<!-- 收货地址action -->
<action name="*spas" class="ShippingAddressAction" method="{1}">
<result name="list">/list.jsp</result>
<!-- 返回action继续调用方法 -->
<result name="find" type="chain">listspas</result>
<result name="update">/update.jsp</result>
</action>
</package>
</struts>
spring.xml/application.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:context="http://www.springframework.org/schema/context"
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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 导入外部的properties配置文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="${initialPoolSize}"></property>
<!--连接池中保留的最小连接数。Default: 3 -->
<property name="minPoolSize" value="3"></property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="${maxPoolSize}"></property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3"></property>
<!--最大空闲时间,1800秒内未使用则连接被丢弃,若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800"></property>
</bean>
<!-- 配置sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 配置hibernate信息 -->
<property name="hibernateProperties">
<props>
<!-- 输出sql语句 -->
<prop key="hibernate.show_sql">true</prop>
<!-- 输出sql的格式化语句 -->
<prop key="hibernate.format_sql">true</prop>
<!-- hibernate自动创建数据库表 update:数据库有这个表级更新,无则创建 -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- 配置数据库格式语言 分页 -> mysql:limit ; oracle:rownum 让hibernate识别不同数据库的语言 -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<!-- 绑定session -->
<prop key="hibernate.current_session_context_class">thread</prop>
</props>
</property>
<property name="mappingLocations">
<list>
<value>classpath:cn/hnck/com/entity/*.hbm.xml</value>
</list>
</property>
</bean>
<!-- 配置事务管理 -->
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- 把事务封装好的一个 面板 -->
<tx:attributes>
<!-- 规定所有find、list、get开头的方法,对数据库只有只读功能 -->
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="list*" read-only="true" />
<!-- 抛出异常回滚事务 -->
<tx:method name="*" rollback-for="Throwable" />
</tx:attributes>
</tx:advice>
<!-- 切入事务开始 织入 -->
<aop:config>
<!-- service层下所有类方法 -->
<aop:pointcut expression="execution(* cn.hnck.com.dao.impl.*.*(..))" id="pointcut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
</aop:config>
<!-- 配置hibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 送货地址管理配置 -->
<!-- AddressDao -->
<bean id="AddressDao" class="cn.hnck.com.dao.impl.AddressDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"></property>
</bean>
<!-- AddressService -->
<bean id="AddressService" class="cn.hnck.com.service.impl.AddressServiceImpl">
<property name="addressDao" ref="AddressDao"></property>
</bean>
<!-- AddressAaction -->
<bean id="ShippingAddressAction" class="cn.hnck.com.action.ShippingAddressAction">
<property name="addressService" ref="AddressService"></property>
</bean>
</beans>
表单页面
index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<a href="listspas.action">我的收货地址</a>
</body>
</html>
save.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>新增收货地址</title>
</head>
<body>
<form action="savespas.action" method="post">
<h1>新增收货地址</h1>
<a href="index.jsp">返回首页</a><br><br>
<table border="1">
<tr>
<td>收货人</td><td> <input type="text" value="收货人姓名" name="recipient"></td>
</tr>
<tr>
<td>手机号 </td><td><input type="text" value="请填写收货手机号" name="mobilePhone"></td>
</tr>
<tr>
<td>收货地址 </td><td><input type="text" value="请选择省/市/县(区)" name="address"></td>
</tr>
<tr>
<td>详细地址</td><td><input type="text" value="请输入详细的地址信息(街道、楼牌号等)" name="detailedAddress"></td>
</tr>
</table>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>
list.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%String context = request.getContextPath(); %>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>新增收货地址</title>
</head>
<body>
<h1 align="left">所有收货地址</h1>
<table border="1">
<tr>
<td>收货人</td>
<td>手机号</td>
<td>收货地址</td>
<td>详细地址</td>
<td>修改地址</td>
<td>删除地址</td>
</tr>
<s:iterator value="list" var="p">
<tr>
<td><s:property value="#p.recipient" /></td>
<td><s:property value="#p.mobilePhone" /></td>
<td><s:property value="#p.address" /></td>
<td><s:property value="#p.detailedAddress" /></td>
<td>
<a href="<%=context %>/FindAddressByIdspas.action?id=<s:property value="#p.id"/>">修改</a>
</td>
<td>
<a href="<%=context %>/deletespas.action?id=<s:property value="#p.id"/>">删除</a>
</td>
</tr>
</s:iterator>
<a href="index.jsp">返回首页</a><br>
<a href="save.jsp">新增收货地址</a>
</table>
<!--分页功能 -->
<br>
<s:set name="page" value="#request['page']"></s:set>
<s:set name="maxPage" value="#request['maxPage']"></s:set>
<s:if test="#page == 1">首页</s:if>
<s:if test="#page > 1 "><a href="<%=context %>/listspas.action?page=1"> 首页</a></s:if>
<s:if test="#page == 1 ">上一页</s:if>
<s:if test="#page > 1 "><a href="<%=context %>/listspas.action?page=<s:property value="#page-1"/>"> 上一页</a></s:if>
<s:if test="#page == #maxPage">下一页</s:if>
<s:if test="#page < #maxPage "><a href="<%=context %>/listspas.action?page=<s:property value="#page+1"/>"> 下一页</a></s:if>
<s:if test="#page == #maxPage">末页</s:if>
<s:if test="#page < #maxPage "><a href="<%=context %>/listspas.action?page=<s:property value="#maxPage"/>">末页</a></s:if>
<br>
</body>
</html>
update.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%String context = request.getContextPath(); %>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>新增收货地址</title>
</head>
<body>
<form action="updatespas.action" method="post">
<h1>修改收货地址</h1>
<table border="1">
<tr>
<td>收货人</td><td><input type="text" value="<s:property value="#updateAddress.recipient" />" name="recipient"></td>
</tr>
<tr>
<td>手机号</td><td><input type="text" value="<s:property value="#updateAddress.mobilePhone" />" name="mobilePhone"></td>
</tr>
<tr>
<td>收货地址</td><td><input type="text" value="<s:property value="#updateAddress.address" />" name="address"></td>
</tr>
<tr>
<td>详细地址</td><td><input type="text" value="<s:property value="#updateAddress.detailedAddress" />" name="detailedAddress"></td>
</tr>
</table>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>