网上有关主从表提交的资料非常的少,可怜我刚刚入门,一切都得自己想办法解决,经过N天的努力,总算是搞定了。程序写的有点徒省事,所以请别见笑。
本来想用struts-nested标签来实现的,折腾了7个小时都搞不定,最后还是用jstl的方式搞定,最然笨了点,但是看着比较容易懂。
下面的代码是主要部分,完整代码请送附件下载(注意编码为utf-8)
用了以下包 dom4j,hibernate3,struts1.2,junit,几个常用apache-commons包,cglib,ehcache,mysql-connector,附件代码里面没有把这些库打包,如果要运行请自己网上下载吧,反正都是开源的
参考文章 www.learntechnology.net/struts-nested.do
这是CustomerAction的部分代码
<ordervalueobject>
下面是用于接收客户信息的值对象的完整代码
</ordervalueobject>
<ordervalueobject><ordervalueobject>
下面是表单bean的完整代码,我不知道用动态bean能不能实现,如果你试成功了,请不要忘了告诉我一声。
</ordervalueobject></ordervalueobject>
这是创建客户信息的jsp页面
</c:url>
本来想用struts-nested标签来实现的,折腾了7个小时都搞不定,最后还是用jstl的方式搞定,最然笨了点,但是看着比较容易懂。
下面的代码是主要部分,完整代码请送附件下载(注意编码为utf-8)
用了以下包 dom4j,hibernate3,struts1.2,junit,几个常用apache-commons包,cglib,ehcache,mysql-connector,附件代码里面没有把这些库打包,如果要运行请自己网上下载吧,反正都是开源的
参考文章 www.learntechnology.net/struts-nested.do
这是CustomerAction的部分代码
java 代码
- public class CustomerAction extends DispatchAction {
- /**
- * 打开客户增加页面
- * @param mapping
- * @param form
- * @param request
- * @param response
- * @return
- * @throws Exception
- */
- public ActionForward openAddCustomer(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
- CustomerValueObject customer = new CustomerValueObject();
- request.setAttribute(Constants.customerBean, customer);
- return mapping.findForward("toAddCustomer");
- }
- /**
- * 保存客户信息
- * @param mapping
- * @param form
- * @param request
- * @param response
- * @return
- * @throws Exception
- */
- public ActionForward saveCustomer(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
- CustomerForm customerForm = (CustomerForm)form;
- Customers customer = null;
- long customerId = customerForm.getCustomer().getId();
- //根据customers.id是否为空判断是插入还是更新
- if (customerForm.getCustomer().getId() == 0){
- customer = this.customerValueObject2Customers(customerForm.getCustomer());
- }else if (customerForm.getCustomer().getId() > 0){
- String hqlString = "select c from Customers c left join fetch c.orderses o where c.id = ?";
- customer = customerDao.getObject(hqlString, new Object[]{new Long(customerId)});
- //或许这里可以用BeanUtils.copyProperty来复制bean的属性,但我试过了,总是报错,索性自己赋值了
- customer.setName(customerForm.getCustomer().getName());
- customer.getOrderses().clear();
- for(Iterator it = customerForm.getCustomer().getOrderses().iterator(); it.hasNext();){
- OrderValueObject orderVo = it.next();
- Orders o = new Orders();
- BeanUtils.copyProperties(o, orderVo);
- customer.getOrderses().add(o);
- o.setCustomers(customer);
- }
- }
- customerDao.saveObject(customer);
- return mapping.findForward("toList");
- }
下面是用于接收客户信息的值对象的完整代码
</ordervalueobject>
java 代码
- package demo.struts.valueobjects;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.commons.collections.Factory;
- import org.apache.commons.collections.ListUtils;
- /**
- * 客户值对象,用于接收表单提交的客户和订单信息
- * @author Administrator
- *
- */
- public class CustomerValueObject implements java.io.Serializable {
- private static final long serialVersionUID = -5142724257544817298L;
- private long id;
- private String name;
- /**
- * 这是关键的一部分,也是和hibernate所用的pojo的唯一区别,这样做是为了解决在没有列表项目的时候,前端页面会报获取第0个元素失败的异常,
- * 这个工具类很好的解决了这个问题,它可以在你访问越界下标元素的时候动态的填充越界的部分,这样就不会报异常了。
- * 下面是这个LazyList的关键代码
- * public Object get(int index) {
- int size = getList().size();
- if (index < size) {
- // within bounds, get the object
- Object object = getList().get(index);
- if (object == null) {
- // item is a place holder, create new one, set and return
- object = factory.create();
- getList().set(index, object);
- return object;
- } else {
- // good and ready to go
- return object;
- }
- } else {
- // we have to grow the list
- for (int i = size; i < index; i++) {
- getList().add(null);
- }
- // create our last object, set and return
- Object object = factory.create();
- getList().add(object);
- return object;
- }
- }
- */
- @SuppressWarnings("unchecked")
- private List orderses = (List)ListUtils.lazyList(new ArrayList(), new Factory(){
- public OrderValueObject create() {
- return new OrderValueObject();
- }
- });
- public CustomerValueObject() {
- }
- public long getId() {
- return this.id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public List getOrderses() {
- return this.orderses;
- }
- public void setOrderses(List orderses) {
- this.orderses = orderses;
- }
- }
下面是表单bean的完整代码,我不知道用动态bean能不能实现,如果你试成功了,请不要忘了告诉我一声。
</ordervalueobject></ordervalueobject>
java 代码
- package demo.struts.forms;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.struts.action.*;
- import demo.struts.valueobjects.*;
- /**
- * ActionForm的代码,里面负责维护一个客户的值对象
- */
- public class CustomerForm extends ActionForm {
- private static final long serialVersionUID = -2128506741766449352L;
- private CustomerValueObject customer;
- public CustomerValueObject getCustomer() {
- return this.customer;
- }
- public void setCustomer(CustomerValueObject customer) {
- this.customer = customer;
- }
- /**
- * 必须在reset中创建客户对象
- */
- @Override
- public void reset(ActionMapping mapping, HttpServletRequest request) {
- customer = new CustomerValueObject();
- super.reset(mapping, request);
- }
- @Override
- public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
- return super.validate(mapping, request);
- }
- }
这是创建客户信息的jsp页面
xml 代码
<%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%> <%@ taglib uri="http://struts.apache.org/tags-nested" prefix="nested"%> > <html> <head> <html:base /> <title>新客户和订单title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <script type="text/javascript"> function onAddOrder(url){ frmCustomer.action = url; frmCustomer.target = "_self"; frmCustomer.submit(); } function onDeleteOrder(url){ frmCustomer.action = url; frmCustomer.submit(); } function onSaveCustomer(url){ frmCustomer.action = url; frmCustomer.submit(); } script> head> <body> <table> <form name="frmCustomer" method="post"> <input type="hidden" name="customer.id" value="${customer.id}" /> <table> <tr> <td> 客户名 td> <td> <input name="customer.name" value="${customer.name}" /> dh> tr> <tr> <td colspan="2"> 订单列表 td> tr> <tr> <div id="orderList"> <table bgcolor="#C0C0C0" width="250px"> <tr> <td> td> <td> 订单号 td> tr> <c:forEach items="${customer.orderses}" var="order" varStatus="orderItems"> <tr> <td> <input type="hidden" name="customer.orderses[${orderItems.index}].id" value="${order.id}" /> td> <td> <input type="text" name="customer.orderses[${orderItems.index}].orderNumber" value="${order.orderNumber}" /> td> <td> <c:url var="deleteOrderUrl" value="/customers.do?method=deleteOrder"> <c:param name="index" value="${orderItems.index}" /> <c:param name="action" value="add" /> c:url> <a href="javascript:onDeleteOrder('${deleteOrderUrl}');">删除订单a> td> tr> c:forEach> <tr> <td align="right" colspan="2"> <c:url var="addOrderUrl" value="/customers.do?method=addOrder"> <c:param name="action" value="add" /> c:url> <a href="javascript:onAddOrder('${addOrderUrl}');">添加订单a> td> tr> table> div> tr> table> form> <tr> <td colspan="2"> <c:url var="saveCustomerUrl" value="/customers.do?method=saveCustomer" /> <html:link href="javascript:onSaveCustomer('${saveCustomerUrl}');">保存客户表单html:link> td> tr> table> body> html>
<c:url var="saveCustomerUrl">
</c:url>