We need to look carefully at the "object" argument. The object here is a Command. LoginController extends SimpleFormController which extends AbstractFormController which extends BaseCommandController which extends AbstractController which extends WebContentGenerator which extends WebApplicationObjectSupport which extends ApplicationObjectSupport. In Spring Web MVC FormControllers, the forms play the role of "commands" in the more general CommandController model. So, in AbstractController there is a final method handleRequest(): Code Block |
---|
title | AbstractController handleRequest() |
---|
|
public final ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// delegate to WebContentGenerator for checking and preparing
checkAndPrepare(request, response, this instanceof LastModified);
// execute in synchronized block if required
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
synchronized (session) {
return handleRequestInternal(request, response);
}
}
}
return handleRequestInternal(request, response);
}
|
As we can see here, it delegates to the method handleRequestInternal(), which is declared to be abstract: Code Block |
---|
title | AbstractController handleRequestInternal() |
---|
|
/**
* Template method. Subclasses must implement this.
* The contract is the same as for handleRequest.
* @see #handleRequest
*/
protected abstract ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception;
|
AbstractCommandController implements this abstract method: Code Block |
---|
title | AbstractCommandController handleRequestInternal() implementation |
---|
|
/**
* Handles two cases: form submissions and showing a new form.
* Delegates the decision between the two to isFormSubmission,
* always treating requests without existing form session attribute
* as new form when using session form mode.
*/
protected final ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
if (isFormSubmission(request)) {
if (isSessionForm() && request.getSession().getAttribute(getFormSessionAttributeName()) == null) {
// cannot submit a session form if no form object is in the session
return handleInvalidSubmit(request, response);
}
// process submit
Object command = getCommand(request);
ServletRequestDataBinder binder = bindAndValidate(request, command);
return processFormSubmission(request, response, command, binder.getErrors());
} else {
return showNewForm(request, response);
}
}
|
LoginController defaults this Command class: Code Block |
---|
title | LoginController afterPropertiesSet() excerpt |
---|
|
public void afterPropertiesSet() throws Exception {
if (this.getCommandClass() == null) {
this.setCommandName("credentials");
this.setCommandClass(UsernamePasswordCredentials.class);
|
In BaseCommandController, we have: Code Block |
---|
title | BaseCommandController getCommand() |
---|
|
/**
* Retrieve a command object for the given request.
* <p>Default implementation calls createCommand. Subclasses can override this.
* @param request current HTTP request
* @return object command to bind onto
* @see #createCommand
*/
protected Object getCommand(HttpServletRequest request) throws Exception {
return createCommand();
}
|
And the createCommand() method to which it delegates: Code Block |
---|
title | BaseCommandController createCommand() |
---|
|
/**
* Create a new command instance for the command class of this controller.
* @return the new command instance
* @throws InstantiationException if the command class could not be instantiated
* @throws IllegalAccessException if the class or its constructor is not accessible
*/
protected final Object createCommand() throws InstantiationException, IllegalAccessException {
if (this.commandClass == null) {
throw new IllegalStateException("Cannot create command without commandClass being set - " +
"either set commandClass or override formBackingObject");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating new command of class [" + this.commandClass.getName() + "]");
}
return this.commandClass.newInstance();
}
|
|