问题:如何取到append操作后的集合
<s:set name="books" value="books"/>
<s:append id="list">
<s:param value="#books"/>
<s:param value="#request.list"/>
</s:append>
<s:property value="@db.MyDb@setBooks(#list)"/>
<%
ArrayList<Book> books1=MyDb.getBooks();
request.setAttribute("newlist", books1);
%>
<s:iterator value="#request.newlist" id="book" status="s">
起因:学习Struts2框架过程中,有一个实验要求用list集合模拟数据库,执行append操作后想要调用静态方法把新的集合赋给原来的集合,发现传入的list并不是一个集合
起初,我以为Struts框架将两个集合合并后会自动转换为我传入时的ArrayList,发现界面输出为空时,我下断调试了一下
调试情况如下:
结果是传入的不是ArrayList,看来至少我学习用的2.1版本并没有我想的这个功能。
通过toString方法得到返回的是AppendIteratorFilter这个类,显然append标签底层通过该类实现操作。
AppendIteratorFilter.java源码如下
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.opensymphony.xwork2.Action;
/**
* A bean that takes several iterators and outputs them in sequence
*
* @see org.apache.struts2.components.AppendIterator
* @see org.apache.struts2.views.jsp.iterator.AppendIteratorTag
*/
public class AppendIteratorFilter extends IteratorFilterSupport implements Iterator, Action {
List iterators = new ArrayList();
// Attributes ----------------------------------------------------
List sources = new ArrayList();
// Public --------------------------------------------------------
public void setSource(Object anIterator) {
sources.add(anIterator);
}
// Action implementation -----------------------------------------
public String execute() {
// Make source transformations
for (int i = 0; i < sources.size(); i++) {
Object source = sources.get(i);
iterators.add(getIterator(source));
}
return SUCCESS;
}
// Iterator implementation ---------------------------------------
public boolean hasNext() {
if (iterators.size() > 0) {
return (((Iterator) iterators.get(0)).hasNext());
} else {
return false;
}
}
public Object next() {
try {
return ((Iterator) iterators.get(0)).next();
} finally {
if (iterators.size() > 0) {
if (!((Iterator) iterators.get(0)).hasNext()) {
iterators.remove(0);
}
}
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
发现next方法的实现很奇怪,把自己写的静态方法参数类型修改为AppendIteratorFilter再次调试一下
((Iterator) iterators.get(0)).next()
就得到了合并后的结果,反复调试,就不难发现,append操作其实是通过合并两个集合的iterator实现的
PS:在非iterator标签AppendIteratorFilter调用next方法后(即本文中在append标签后iterator标签前),会改变AppendIteratorFilter next指针,此时若再返回到jsp界面仍使用append标签name属性定义的集合进行遍历操作会没有输出结果