記一次Struts踩坑例項
阿新 • • 發佈:2019-01-05
問題:如何取到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="@[email protected](#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屬性定義的集合進行遍歷操作會沒有輸出結果