Here's how Struts 2
(one of the best MVC frameworks) handles a typical User Registration.
Registration Page --Submit-->
Filter Dispatcher (Controller) --Struts-->
Interceptor --Stack--> Validator --Passed-->
Action (Model)
--Invokes--> Service/DAO Layer --Persists--> Database
Result <--returns-- Action
JSP (View) (selected based on result)
Interceptor (any post-processing)
Registration Success HTML
Unlike Servlets
you don't actually write any controller; you just configure the framework declaratively using Struts.xml
and it then orchestrates the whole MVC flow as configured.
The Controller
performs the validation through Interceptors and passes a pre-populated and validated data object to the model for persisting into the database.
public class UserRegistrationAction {
private User user = new User();
public User getModel() { // Struts Callback
return user; // automatically gets populated with validated values
}
// This will seem incorrect to someone used to Spring's setter injection but
// Struts injects in reverse; pulls the model onto a ValueStack to inject properties
public String execute() {
// already validated; simply persist
UserRegistrationService.getInstance().persist(getUser());
return Action.SUCCESS;
}
...
}
So, yes you're correct in implementing validations in your controller.
But, with that said, any processing on the data should always happen in the Model itself. Suppose you had also asked your users if they would like to import their Facebook friends list or GMail contacts list and they agreed and supplied the necessary details then:
public String execute() {
user.setContactsList(
thirdPartyService.getInstance(getPartyCode()).fetchContacts(user.getAuthInfo())
);
UserRegistrationService.getInstance().persist(getUser());
return Action.SUCCESS;
}
The logic of authenticating with the third party service and fetching other details to update your User object (before you persist it) would also go in your Model. That's because this constitutes your business logic and should be encapsulated in your stand-alone re-usable model classes independent of which technology you use for implementing your controllers (Servlets, Stuts or Spring MVC).
So, ideally you would only factor out cross-cutting concerns (like validation, authentication, caching etc.) into Controllers and leave your core business logic within Models.