有的時(shí)候,我們會(huì)選擇不采用struts的html便簽等等,其實(shí)這樣的話,不是一個(gè)很好的處理,因?yàn)閟truts的標(biāo)簽不僅僅是相對(duì)于重復(fù)代碼的封裝,更多的是為了配合其自身某些功能的實(shí)現(xiàn);
比如,我們會(huì)問,為什么我們會(huì)使用html標(biāo)簽?zāi)兀娴谋任覀冎苯邮褂胔tml標(biāo)簽更加的方便嗎,我們還得花費(fèi)時(shí)間來學(xué)習(xí)他,其實(shí)不是這樣的,考試.大提示看了下面的例子就會(huì)明白;
一個(gè)頁面有兩個(gè)標(biāo)簽,分別采用的是上面的兩種表單形式,我們?cè)赼ctionmapping的action中進(jìn)行配置;
我們可以看見我們把scope設(shè)置成為了session,我們填充這個(gè)表單進(jìn)行提交到一個(gè)新的頁面,然后在往回跳轉(zhuǎn),如果采用struts的html標(biāo)簽的話,我們可以看見我們的表單中自動(dòng)填充了我們進(jìn)行提交的值,而如果我們采用的是html的標(biāo)簽,那么這個(gè)表單是空的,默認(rèn)實(shí)現(xiàn)的,這一節(jié),我們來分析一個(gè)html表單與后臺(tái)的對(duì)應(yīng),以及后臺(tái)的值如何推到前臺(tái);
首先,在頁面上,腳本會(huì)將前臺(tái)頁面的表單form與后臺(tái)的actionForm對(duì)應(yīng)起來,這是前臺(tái)與后臺(tái)的對(duì)應(yīng),我們來看一下如何實(shí)現(xiàn)的:
在RequestProcessor的process的方法中,存在下面兩句代碼:
ActionForm form = processActionForm(request, response, mapping);
processPopulate(request, response, form, mapping);
protected ActionForm processActionForm(HttpServletRequest request,
HttpServletResponse response, ActionMapping mapping) {
//生成一個(gè)新的ActionForm
ActionForm instance =
RequestUtils.createActionForm(request, mapping, moduleConfig,
servlet);
if (instance == null) {
return (null);
}
// Store the new instance in the appropriate scope
if (log.isDebugEnabled()) {
log.debug(" Storing ActionForm bean instance in scope '"
+ mapping.getScope() + "' under attribute key '"
+ mapping.getAttribute() + "'");
}
//從ActionMapping中得到其scope,保存到設(shè)置的范圍中;
if ("request".equals(mapping.getScope())) {
request.setAttribute(mapping.getAttribute(), instance);
} else {
HttpSession session = request.getSession();
session.setAttribute(mapping.getAttribute(), instance);
}
return (instance);
}
在createActionForm方法中,我們可見如下:
ActionForm instance =
//在其范圍域中查找ActionForm對(duì)象,如果存在則復(fù)用,
lookupActionForm(request, attribute, mapping.getScope());
if ((instance != null) && config.canReuse(instance)) {
return (instance);
}
//如果不存在,則重新生成新的;
return createActionForm(config, servlet);
在populate方法中,有如下:
如果不是上傳的文件,那么:
if (!isMultipart) {
names = request.getParameterNames();
}
//得到該頁面提交的參數(shù)
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
String stripped = name;
if (prefix != null) {
if (!stripped.startsWith(prefix)) {
continue;
}
stripped = stripped.substring(prefix.length());
}
if (suffix != null) {
if (!stripped.endsWith(suffix)) {
continue;
}
stripped =
stripped.substring(0, stripped.length() - suffix.length());
}
Object parameterValue = null;
if (isMultipart) {
parameterValue = multipartParameters.get(name);
} else {
parameterValue = request.getParameterValues(name);
}
// Populate parameters, except "standard" struts attributes
// such as 'org.apache.struts.action.CANCEL'
if (!(stripped.startsWith("org.apache.struts."))) {
properties.put(stripped, parameterValue);
}
}
// 將參數(shù)和actionForm的屬性對(duì)應(yīng)起來;形成了頁面數(shù)據(jù)和后臺(tái)的對(duì)應(yīng);
try {
BeanUtils.populate(bean, properties);
} catch (Exception e) {
throw new ServletException("BeanUtils.populate", e);
} finally {
if (multipartHandler != null) {
// Set the multipart request handler for our ActionForm.
// If the bean isn't an ActionForm, an exception would have been
// thrown earlier, so it's safe to assume that our bean is
// in fact an ActionForm.
((ActionForm) bean).setMultipartRequestHandler(multipartHandler);
}
}
}
我們可以看見知道這里為止,前臺(tái)頁面和后臺(tái)的數(shù)據(jù)對(duì)應(yīng)起來了。那么,我們?cè)趺纯赡苁沟眯薷暮笈_(tái)的actionForm表單的數(shù)據(jù)使得前臺(tái)和后臺(tái)的數(shù)據(jù)對(duì)應(yīng)起來呢?就像我們一開始的時(shí)候那樣,actionForm是session范圍的,使用了struts的標(biāo)簽我們依然能夠使得其自動(dòng)填充表單;
那么我們就要分析一下struts的標(biāo)簽了;
首先,在頁面上,我們會(huì)解析標(biāo)簽,表單控件要與后臺(tái)對(duì)應(yīng)起來,那么這個(gè)對(duì)應(yīng)的單位是form,所以,空間應(yīng)用都被包含在一個(gè)form中;
public class FormTag extends TagSupport
form表單據(jù)稱于TagSupport,他為整個(gè)表單與后臺(tái)的對(duì)應(yīng)做了很多預(yù)先的工作;
public int doStartTag() throws JspException {
postbackAction = null;
//查找表單的范圍域,bean的名字,以及類型;
this.lookup();
//生成html的form控件的text;
StringBuffer results = new StringBuffer();
results.append(this.renderFormStartElement());
results.append(this.renderToken());
//將

