第7部分
上一篇文章中介紹校驗時提到客戶邊的校驗用到了JavaScript,實際上用Struts配合JavaScript還可以實現許多有用的功能,比如,級聯下拉菜單的實現就是一個典型的例子:
本例假設要實現的是一個文章發布系統,我們要發布的文章分為新聞類和技術類,其中新聞類又分為時事新聞和行業動態;技術類又分為操作系統、數據庫、和編程語言等,為了便于添加新的條目,所有這些都保存在數據庫表中。
為此,我們建立一個名為articleClass的表和一個名為articleSubClass的表。
articleClass表的結構如下:
articleClassID字段:char類型,長度為2,主鍵
articleClassName字段:varchar類型,長度為20
articleSubClass表的結構如下:
articleClassID字段:char類型,長度為2
articleSubClassID字段:char類型,長度為2與articleClassID一起構成主鍵
articleSubClassName字段:varchar類型,長度為20
表建好后,在articleClass表中錄入如下數據:如,01、新聞類;02、技術類
在articleSubClass表中錄入:01、01、時事新聞;01、02、行業動態;02、01、操作系統等記錄。到這里,數據庫方面的準備工作就已做好。
有了前面做登錄例子的基礎,理解下面要進行的工作就沒有什么難點了,我們現在的工作也在原來mystruts項目中進行。首先,建立需要用到的formbean即ArticleClassForm,其代碼如下:
package entity;
import org.apache.struts.action.*;
import javax.servlet.http.*;
import java.util.Collection;public class ArticleClassForm extends ActionForm {//為select的option做準備private Collection beanCollection;private String singleSelect = "";private String[] beanCollectionSelect = { "" };private String articleClassID;private String articleClassName;private String subI;//子類所在行數private String subJ;//子類所在列數private String articleSubClassID;private String articleSubClassName;public Collection getBeanCollection(){return beanCollection;}public void setBeanCollection(Collection beanCollection){this.beanCollection=beanCollection;}public String getSingleSelect() {return (this.singleSelect);}public void setSingleSelect(String singleSelect) {this.singleSelect = singleSelect;}public String[] getBeanCollectionSelect() {return (this.beanCollectionSelect);}public void setBeanCollectionSelect(String beanCollectionSelect[]) {this.beanCollectionSelect = beanCollectionSelect;}public String getArticleClassID() {return articleClassID;}public void setArticleClassID(String articleClassID) {this.articleClassID = articleClassID;}public String getArticleClassName() {return articleClassName;}public void setArticleClassName(String articleClassName) {this.articleClassName = articleClassName;}public String getSubI() {return subI;}public void setSubI(String subI) {this.subI = subI;}public String getSubJ() {return subJ;}public void setSubJ(String subJ) {this.subJ = subJ;}public String getArticleSubClassID() {return articleSubClassID;}public void setArticleSubClassID(String articleSubClassID) {this.articleSubClassID = articleSubClassID;}public String getArticleSubClassName() {return articleSubClassName;}public void setArticleSubClassName(String articleSubClassName) {this.articleSubClassName = articleSubClassName;}
}
將它放在包entity中。其次,我們的系統要訪問數據庫,因此也要建立相應的數據庫訪問對象ArticleClassDao,其代碼如下:
package db;import entity.ArticleClassForm;
import db.*;
import java.sql.*;import java.util.Collection;
import java.util.ArrayList;
import org.apache.struts.util.LabelValueBean;
public class ArticleClassDao {private Connection con;public ArticleClassDao(Connection con) {this.con=con;}public Collection findInUseForSelect(){PreparedStatement ps=null;ResultSet rs=null;ArrayList list=new ArrayList();String sql="select * from articleClass order by articleClassID";try{if(con.isClosed()){throw new IllegalStateException("error.unexpected");}ps=con.prepareStatement(sql);rs=ps.executeQuery();while(rs.next()){String value=rs.getString("articleClassID");String label=rs.getString("articleClassName");list.add(new LabelValueBean(label,value));}return list;}catch(SQLException e){e.printStackTrace();throw new RuntimeException("error.unexpected");}finally{try{if(ps!=null)ps.close();if(rs!=null)rs.close();}catch(SQLException e){e.printStackTrace();throw new RuntimeException("error.unexpected");}}}public Collection findInUseForSubSelect(){PreparedStatement ps=null;ResultSet rs=null;PreparedStatement psSub=null;ResultSet rsSub=null;int i=0;//大類記數器int j=0;//小類記數器String classID="";String subClassID="";String subClassName="";ArrayList list=new ArrayList();ArticleClassForm articleClassForm;String sql="select * from articleClass order by articleClassID";try{if(con.isClosed()){throw new IllegalStateException("error.unexpected");}ps=con.prepareStatement(sql);rs=ps.executeQuery();while(rs.next()){i++;classID=rs.getString("articleClassID");String sqlSub="select * from articleSubClass where articleClassID=? order by articleSubClassID";psSub=con.prepareStatement(sqlSub);psSub.setString(1,classID);rsSub=psSub.executeQuery();articleClassForm=new ArticleClassForm();articleClassForm.setSubI(""+i);articleClassForm.setSubJ(""+j);articleClassForm.setArticleSubClassID("請輸入一個小類");articleClassForm.setArticleSubClassName("請輸入一個小類");list.add(articleClassForm);while(rsSub.next()){subClassID=rsSub.getString("articleSubClassID");subClassName=rsSub.getString("articleSubClassName");j++;//optionStr="articleSubClassGroup[" + i + "][" + j + "]=
new Option('"+ subClassName +"','"+ subClassID+ "')";articleClassForm=new ArticleClassForm();articleClassForm.setSubI(""+i);articleClassForm.setSubJ(""+j);articleClassForm.setArticleSubClassID(subClassID);articleClassForm.setArticleSubClassName(subClassName);list.add(articleClassForm);}j=0;}return list;}catch(SQLException e){e.printStackTrace();throw new RuntimeException("error.unexpected");}finally{try{if(ps!=null)ps.close();if(rs!=null)rs.close();}catch(SQLException e){e.printStackTrace();throw new RuntimeException("error.unexpected");}}}
}
將它保存在db目錄中。它們的目的是將文章的類和子類信息從數據庫表中讀出,以一定的格式保存在集合對象中以供頁面顯示。
再次,我們要建立相應的jsp文件,文件名為selectArticleClass.jsp,代碼如下:
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
<head>
<title>
選擇文件類別
</title>
</head>
<body bgcolor="#ffffff">
<h3>
選擇文件所屬類型
</h3>
<html:errors/>
<table width="500" border="0" cellspacing="0" cellpadding="0"><tr><td><html:form name="articleClassForm" type="entity.ArticleClassForm"action="selectArticleClassAction.do"><table width="500" border="0" cellspacing="0" cellpadding="0"><tr><td align="right">文章大類*</td><td><html:select property="articleClassID" styleClass="word"οnchange="articleClassFormredirect(this.options.selectedIndex)"><html:option value="">請選擇一個大類</html:option><html:optionsCollection name="articleClassForm" property="beanCollection" styleClass="word"/></html:select></td></tr><tr><td align="right">文章小類*</td><td><select name="articleSubClassID" Class="word" ><option value="">請選擇一個小類</option></select><SCRIPT language=JavaScript><!--var articleSubClassGroups=document.articleClassForm.articleClassID.options.lengthvar articleSubClassGroup=new Array(articleSubClassGroups)for (i=0; i<articleSubClassGroups; i++)articleSubClassGroup[i]=new Array()<logic:iterate name="articleSubClassList" id="articleClassForm"scope="request" type="entity.ArticleClassForm">articleSubClassGroup[<bean:write name="articleClassForm"property="subI"/>][<bean:write name="articleClassForm"property="subJ"/>]=new Option("<bean:write name="articleClassForm"property="articleSubClassName"/>","<bean:write name="articleClassForm"property="articleSubClassID"/>")</logic:iterate>var articleSubClassTemp=document.articleClassForm.articleSubClassIDfunction articleClassFormredirect(x){for (m=articleSubClassTemp.options.length-1;m>0;m--)articleSubClassTemp.options[m]=nullfor (i=0;i<articleSubClassGroup[x].length;i++){articleSubClassTemp.options[i]=newOption(articleSubClassGroup[x][i].text,articleSubClassGroup[x][i].value)}articleSubClassTemp.options[0].selected=true}//--></SCRIPT></td></tr></table></html:form></td></tr>
</table>
</body>
</html>
這里值得重點關注的是其中的JavaScript代碼,有興趣的可以仔細分析一下它們是怎樣配合集合中的元素來實現級聯選擇的。
最后,為了例子的完整。我們將涉及到action代碼和必要的配置代碼在下面列出:其中,action的文件名為SelectArticleClassAction.java,代碼如下:
package action;
import entity.*;
import org.apache.struts.action.*;
import javax.servlet.http.*;
import javax.sql.DataSource;
import java.sql.Connection;
import db.ArticleClassDao;
import java.util.Collection;
import java.sql.SQLException;
public class SelectArticleClassAction extends Action {public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm,HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {/**@todo: complete the business logic here, this is just a skeleton.*/ArticleClassForm articleClassForm = (ArticleClassForm) actionForm;DataSource dataSource;Connection cnn=null;ActionErrors errors=new ActionErrors();try{dataSource = getDataSource(httpServletRequest,"A");cnn = dataSource.getConnection();ArticleClassDao articleClassDao=new ArticleClassDao(cnn);Collection col=articleClassDao.findInUseForSelect();articleClassForm.setBeanCollection(col);httpServletRequest.setAttribute("articleClassList",col);//處理子類選項Collection subCol=articleClassDao.findInUseForSubSelect();httpServletRequest.setAttribute("articleSubClassList",subCol);return actionMapping.findForward("success");}catch(Throwable e){e.printStackTrace();//throw new RuntimeException("未能與數據庫連接");ActionError error=new ActionError(e.getMessage());errors.add(ActionErrors.GLOBAL_ERROR,error);}finally{try{if(cnn!=null)cnn.close();}catch(SQLException e){throw new RuntimeException(e.getMessage());}}saveErrors(httpServletRequest,errors);return actionMapping.findForward("fail");}
}
將其保存在action目錄中。
在struts-config.xml文件中做如下配置:
在
<form-beans>
中加入
<form-bean name="articleClassForm" type="entity.ArticleClassForm" />
在
<action-mappings>
中加入:
<action name="articleClassForm" path="/selectArticleClassAction" scope="session"type="action.SelectArticleClassAction" validate="false">
<forward name="success" path="/selectArticleClass.jsp" />
<forward name="fail" path="/genericError.jsp" />
</action>
為了對應配置中的
<forward name="fail" path="/genericError.jsp" />
,我們還要提供一個顯示錯誤信息的jsp頁面,其代碼如下:
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<head>
<title>
genericError
</title>
<link href="css/mycss.css" rel="stylesheet" type="text/css">
</head>
<body bgcolor="#ffffff">
<html:errors/>
</body>
</html>
現在一切就緒,可以編譯執行了。在瀏覽器中輸入:http://127.0.0.1:8080/mystruts/selectArticleClassAction.do就可以看到該例子的運行結果了。(T111)
本文作者:張永美 羅會波 湖北省當陽市國稅局 可通過lhbf@sina.com與他們聯系
轉載地址:http://www.cnblogs.com/SGSoft/articles/88251.html
總結
以上是生活随笔為你收集整理的struts原理与实践(七)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。