Struts原理與實踐(7) - -
在上一篇文章中介紹校驗時提到客戶邊的校驗用到了JavaScript,實際上用Struts配合JavaScript還可以實現(xiàn)許多有用的功能,,比如,,級聯(lián)下拉菜單的實現(xiàn)就是一個典型的例子:
本例假設要實現(xiàn)的是一個文章發(fā)布系統(tǒng),,我們要發(fā)布的文章分為新聞類和技術類,,其中新聞類又分為時事新聞和行業(yè)動態(tài);技術類又分為操作系統(tǒng),、數(shù)據(jù)庫,、和編程語言等,為了便于添加新的條目,,所有這些都保存在數(shù)據(jù)庫表中,。
為此,我們建立一個名為articleClass的表和一個名為articleSubClass的表,。
articleClass表的結構如下:
articleClassID字段:char類型,,長度為2,主鍵
articleClassName字段:varchar類型,,長度為20
articleSubClass表的結構如下:
articleClassID字段:char類型,,長度為2
articleSubClassID字段:char類型,長度為2與articleClassID一起構成主鍵
articleSubClassName字段:varchar類型,,長度為20 |
表建好后,在articleClass表中錄入如下數(shù)據(jù):如,01、新聞類,;02,、技術類
在articleSubClass表中錄入:01,、01,、時事新聞,;01,、02,、行業(yè)動態(tài),;02,、01、操作系統(tǒng)等記錄,。到這里,數(shù)據(jù)庫方面的準備工作就已做好,。
有了前面做登錄例子的基礎,,理解下面要進行的工作就沒有什么難點了,我們現(xiàn)在的工作也在原來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;//子類所在行數(shù)
private String subJ;//子類所在列數(shù)
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中。其次,,我們的系統(tǒng)要訪問數(shù)據(jù)庫,因此也要建立相應的數(shù)據(jù)庫訪問對象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;//大類記數(shù)器
int j=0;//小類記數(shù)器
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目錄中。它們的目的是將文章的類和子類信息從數(shù)據(jù)庫表中讀出,,以一定的格式保存在集合對象中以供頁面顯示,。
再次,我們要建立相應的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"
onchange="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.length
var 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.articleSubClassID
function articleClassFormredirect(x){
for (m=articleSubClassTemp.options.length-1;m>0;m--)
articleSubClassTemp.options[m]=null
for (i=0;i<articleSubClassGroup[x].length;i++){
articleSubClassTemp.options[i]=new
Option(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代碼,有興趣的可以仔細分析一下它們是怎樣配合集合中的元素來實現(xiàn)級聯(lián)選擇的。
最后,,為了例子的完整,。我們將涉及到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("未能與數(shù)據(jù)庫連接");
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-bean name="articleClassForm" type="entity.ArticleClassForm" /> |
在
中加入:
<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> |
現(xiàn)在一切就緒,,可以編譯執(zhí)行了。在瀏覽器中輸入:http://127.0.0.1:8080/mystruts/selectArticleClassAction.do就可以看到該例子的運行結果了,。(T111)
|