FormBean到底是什么?
我们在Struts FrameWork里我们在配置config的时候要配置一个FormBean,相信有些人会和我有同样的困惑,这个FormBean在整个FrameWork里扮演的是一个什么样的角色,它到底有什么样的作用。带着这些疑惑,我们来跟踪一下这个FormBean在FrameWork里到底干了些什么?怎么做的?
我们在web模块的web-inf目录下找到struts-config.xml这个XML配置文件,从下面这个目录里我们可以看到struts-config.xml配置文件可以分成很多个的,这样便于配置文件的管理,一个模块对应一个配置文件,非常清晰。我们打开其中的一个Config配置文件(如红色框的文件)
我们在配置文件里看到有<form-beans>标签这里定义的是这个模块所需要的FormBean如下图所示,这里type="butone.hr.rcyw.ldht.object.LDHTVO"是指FormBean的包路径,名称为name="LDHTVO",我们再在下面的<action-mappings>标签里可以看到一个action对应一个FormBean,由此可以知道Action与FormBean是一一对应且是唯一的。
我们再打开LDHTAction这个文件看看,我们在文件中根据传递的cmdFlag为“select”可以看到一下代码:
LDHTPageInfoVO aLDHTPageInfoVO = new LDHTPageInfoVO();
aLDHTPageInfoVO.queryCommCondition = SelectCondition.toString();
Vector result = aLDHTService.selectLDHTList(aLDHTPageInfoVO);
request.setAttribute("pageResult", result);
从这段代码里我们完全看不到LDHTVO这个VO,我们发现只有LDHTPageInfoVO,我们再看看这个VO里到底有些什么东西:
public class LDHTPageInfoVO extends PageInfoVO {
public LDHTPageInfoVO() {
orderName = LDHTConstant.DEFAULT_ORDER_NAME;
orderType = LDHTConstant.DEFAULT_ORDER_TYPE;
rowsPerPage = LDHTConstant.ROWS_PER_PAGE;
tableName = LDHTConstant.VIEW_NAME;
listNames = LDHTConstant.SELECT_COLS;
}
}
原来仅仅继承了一个分页的PageInfoVO,里面还有分页的信息。
我们继续跟踪这段话Vector result = aLDHTService.selectLDHTList(aLDHTPageInfoVO);
打开LDHTService这个类找到selectLDHTList这个方法
public Vector selectLDHTList(PageInfoVO apageInfoVO) throws Exception {
return aLDHTLocal.selectLDHTList(apageInfoVO);
}
这个方法只有一句话,调用了一个SessionBean方法LDHTHandle,打开这个SessionBean我们可以找到这个方法如下:
public Vector selectLDHTList(PageInfoVO apageInfoVO) throws Exception {
LDHTVO aLDHTVO = new LDHTVO();
LDHTDBAccess aDBAccess = new LDHTDBAccess();
return aDBAccess.selectPage(apageInfoVO, aLDHTVO);
}
哈哈,终于出现LDHTVO了,这个方法调用了一个LDHTDBAccess类里的selectPage方法并传入了两个参数其中一个是分页信息,另一个就是LDHTVO这个VO。
我们继续跟踪看看selectPage这个方法到底干了些什么? 打开LDHTDBAccess这个类找到selectPage这个方法:
public class LDHTDBAccess extends DBPageBean {
/**
* Description: 删除一条记录
* @param String id
* @return void
* @throw Exception
*/
public void deleteOne(String id) throws Exception {
StringBuffer SQL = new StringBuffer();
SQL.append("delete from ");
SQL.append(LDHTConstant.TABLE_NAME);
SQL.append(" where ");
SQL.append(LDHTConstant.KEY_NAME);
SQL.append("='");
SQL.append(id);
SQL.append("'");
exectueSql(SQL.toString());
}
/**
* @method isIllegal 判断该对象是否符合插入、修改编号原则-
* @param bo
* @return 合法则返回true ,不合法则返回false
*/
public boolean isIllegal(LDHTBO bo) {
return true;
}
}//End.
我们发现这个类里除了这两个类之外,没有其他方法,但是它继承了DBPageBean这个父类,这个父类是框架里的,这难不倒我们,我们找到框架的这个foundationv2.jar 包反编译看看,
public Vector selectPage(PageInfoVO apageInfoVO, BaseVO aBaseVO)
throws Exception
{
return readPage(apageInfoVO, aBaseVO);
}
用了一个readPage这个方法,
public Vector readPage(PageInfoVO pageInfoVO, BaseBO aBaseBO)
{
ResultSet pageRs = null;
Connection conn = null;
PreparedStatement pstmt = null;
try
{
Vector aVector = new Vector();
int acurPage = pageInfoVO.curPage;
Comm.log(1, "当前翻页Bean开始执行翻页操作:检索第" + acurPage + "页");
try
{
calMaxRowCount(pageInfoVO);
calMaxPage(pageInfoVO);
pageInfoVO.querySql = createQuerySql(pageInfoVO);
Comm.log(1, "查询翻页的SQL=" + pageInfoVO.querySql);
calMaxPage(pageInfoVO);
if(acurPage > pageInfoVO.maxPage)
acurPage = pageInfoVO.maxPage;
setCurPage(acurPage, pageInfoVO);
conn = getConn();
pstmt = getPstmt(conn, pageInfoVO.querySql);
pageRs = pstmtQuery(pstmt);
if(pageRs != null)
{
Comm.log(1, "当前翻页Bean查出的最大行数:" + pageInfoVO.maxRowCount);
Comm.log(1, "当前翻页Bean查出的最大页数:" + pageInfoVO.maxPage);
}
calCurMaxRows(pageInfoVO);
}
catch(Exception ex)
{
pageRs = null;
ex.printStackTrace();
}
BaseVO aBaseVOs[] = (BaseVO[])null;
if(pageInfoVO.rowsPerPage != -1)
aBaseVOs = new BaseVO[pageInfoVO.curMaxRow];
else
aBaseVOs = new BaseVO[pageInfoVO.maxRowCount];
int i = 0;
if(pageInfoVO.curPage > 1 && pageInfoVO.rowsPerPage != -1)
pageRs.absolute(pageInfoVO.rowsPerPage * (pageInfoVO.curPage - 1));
Comm.log(1, "当前翻页Bean的结果集滚动=" + pageInfoVO.rowsPerPage * (pageInfoVO.curPage - 1));
while(pageRs.next())
{
aVector.add(parseResultToSimpleBaseBO(pageRs, aBaseBO, pageInfoVO.listNames));
i++;
}
if(pageInfoVO.maxRowCount == 0)
pageInfoVO.curPage = 0;
aVector.add(pageInfoVO);
Comm.log(1, "翻页的Vector: length=" + aVector.size());
Vector vector = aVector;
return vector;
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
freeConn(pageRs, pstmt, conn);
}
return null;
}
其实在这个方法里就是把查出来的多条数据每一条保存到一个LDHTVO里然后再保存到一个Vector里,返回。
至此我们可以在Action里看到返回的Vector其实就是一系列的LDHTVO。再到JSP页面我们可以看到
Vector LDHTVOs = (Vector)request.getAttribute("pageResult");
if (LDHTVOs != null) {
for (int i =0 ; i< LDHTVOs.size()-1; i++) {
LDHTVO aLDHTVO = (LDHTVO)LDHTVOs.get(i);
%>
<tr class="normal" clickType="1" onClick="parent.showSub(parent.currentID, '<%=aLDHTVO.getLDHTID()%>')" id="<%=aLDHTVO.getLDHTID()%>">
<!--td><input name="checkbox" type="checkbox" value="<%=aLDHTVO.getLDHTID()%>"></td-->
<td nowrap id="<%=aLDHTVO.getRYXXID()%>" class="ryxxwindow" ><%=aLDHTVO.getRYBH() %></td>
<td nowrap><%=aLDHTVO.getXM() %></td>
<td nowrap><%=aLDHTVO.getXB() %></td>
<td nowrap><%=aLDHTVO.getNL() %></td>
<td nowrap><%=aLDHTVO.getGL() %></td>
<td nowrap><%=aLDHTVO.getJGMC() %></td>
<td nowrap><%=aLDHTVO.getBMMC() %></td>
<td nowrap><%=aLDHTVO.getYGLB() %></td>
<td nowrap><%=aLDHTVO.getZT() %></td>
<td nowrap><%=aLDHTVO.getHTDQRQ()%></td>
<td nowrap><%=aLDHTVO.getHTZZRQ()%></td>
</tr>
<%}}%>
这样的代码其实就是把Vector里的VO拿出来,再把VO里的数据取出来。
其实到此为止,我们还没有看出这个FormBean到底有什么过人之处,下面我们来看看Edit操作,也就是在页面上修改一条数据,然后保存到数据库里去,
我们首先打开JSP页面看到以下代码
<input name="cmdFlag" type="hidden" value="Save">
我们发现input表单的Name与VO里的名字一样,然后我们再到Action里看看
} else if (cmdFlag.equals("Save")) {
LDHTVO aVO = (LDHTVO) form;
LDHTBO aBO = (LDHTBO) convertVOtoBO(aVO, aUserBean);
try {
aLDHTService.saveLDHT(aBO);
aVO.DIRTYFLAG = aBO.DIRTYFLAG;
} catch (Exception e) {
e.printStackTrace();
if (aBO.isNew()) {
aVO.setLDHTID("");
}
request.setAttribute("alertMsg", "保存记录出错,错误原因:" + BTDBHelper.getMessage(e));
}
request.setAttribute("Detail_LDHTVO", aVO);
return (mapping.findForward("LDHTEdit"));
}
我们可以看到form其实就是VO即FormBean,这样我们提交表单方便很多,省去了好多代码。
至此FormBean全部解析完毕。
作者:Anders xiao