Spring MVC 框架学习之AbstractFormController以及AbstractFormControll

本文解析了Spring MVC中的FormController流程,重点介绍了AbstractFormController及其实现SimpleFormController的工作原理。阐述了请求处理、数据绑定验证及视图展示等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在看完BaseCommandController和AbstractCommandController之后,我们再看BaseCommandController的另一个实现AbstractFormController,以及AbstractFormController的具体实现SimpleFormController。

先看看AbstractFormController对handleRequestInternal的实现:

protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Form submission or new form to show?
if (isFormSubmission(request)) {
// Fetch form object from HTTP session, bind, validate, process submission.
try {
Object command = getCommand(request);
ServletRequestDataBinder binder = bindAndValidate(request, command);
BindException errors = new BindException(binder.getBindingResult());
return processFormSubmission(request, response, command, errors);
}
catch (HttpSessionRequiredException ex) {
// Cannot submit a session form if no form object is in the session.
if (logger.isDebugEnabled()) {
logger.debug("Invalid submit detected: " + ex.getMessage());
}
return handleInvalidSubmit(request, response);
}
}
else {
// New form to show: render form view.
return showNewForm(request, response);
}
}
这个方法,首先判断是不是Form提交,判断方法是:
protected boolean isFormSubmission(HttpServletRequest request) {
return "POST".equals(request.getMethod());
}
如果是form提交的话,系统首先创建一个Command,然后对数据进行绑定和验证,之后调用processFormSubmission方法。showNewForm则调用showForm。
在AbstractFormController中里面有两个抽象方法:

protected abstract ModelAndView processFormSubmission(
HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)
throws Exception;
protected abstract ModelAndView showForm(
HttpServletRequest request, HttpServletResponse response, BindException errors)
throws Exception;



 
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: Consolas, "Courier New", Courier, Monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>

 

好了,看完AbstractFormController之后,再看看SimpleFormController是如何实现:

protected ModelAndView processFormSubmission(
HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)
throws Exception {

if (errors.hasErrors()) {
if (logger.isDebugEnabled()) {
logger.debug("Data binding errors: " + errors.getErrorCount());
}
return showForm(request, response, errors);
}
else if (isFormChangeRequest(request, command)) {
logger.debug("Detected form change request -> routing request to onFormChange");
onFormChange(request, response, command, errors);
return showForm(request, response, errors);
}
else {
logger.debug("No errors -> processing submit");
return onSubmit(request, response, command, errors);
}
}
在上面的方法中,如果有错误,调用showForm,来显示form。没有错误的话,则调用onSubmit方法。
protected final ModelAndView showForm(
HttpServletRequest request, BindException errors, String viewName, Map controlModel)
throws Exception {

// In session form mode, re-expose form object as HTTP session attribute.
// Re-binding is necessary for proper state handling in a cluster,
// to notify other nodes of changes in the form object.
if (isSessionForm()) {
String formAttrName = getFormSessionAttributeName(request);
if (logger.isDebugEnabled()) {
logger.debug("Setting form session attribute [" + formAttrName + "] to: " + errors.getTarget());
}
request.getSession().setAttribute(formAttrName, errors.getTarget());
}

// Fetch errors model as starting point, containing form object under
// "commandName", and corresponding Errors instance under internal key.
Map model = errors.getModel();

// Merge reference data into model, if any.
Map referenceData = referenceData(request, errors.getTarget(), errors);
if (referenceData != null) {
model.putAll(referenceData);
}

// Merge control attributes into model, if any.
if (controlModel != null) {
model.putAll(controlModel);
}

// Trigger rendering of the specified view, using the final model.
return new ModelAndView(viewName, model);
}
在showForm中,设置属性,放在model中,然后在viewName进行设置。
FormController就是上面的过程。具体的执行过程和详细信息会在以后的博客中具体介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值