0

I would like some thoughts on where you would process a form submission in a MVC framework? Would you have a Model handling the logic or process it directly in the controller?

Let's assume that this is a registration form, that will end up createing a user in the database.

How would you approach something like that?

The way I would go about it, is to validate the form data in the controller, create a User model with the data and save it to the database. However, I have seen Models dealing specifically with Form data (the Controller loads a Form model passing it the $_POST data) and I am wondering if it is necessary

Thanks

Thomas
  • 4,641
  • 13
  • 44
  • 67

2 Answers2

0

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.

Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89
  • Xm.... This in essence is the exact opposite of what Didaxis proposes and more in what I had in mind to begin with. Thanks. Would appreciate some more input from others too. Very consice explanation however – Thomas Apr 28 '13 at 19:41
  • @Thomas Updated to better explain `getModel()`. Please tag your question with `java`, `java-ee` for more responses. – Ravi K Thapliyal Apr 28 '13 at 20:14
  • Hi Ravi. Basically, I am a PHP guy. But I believe that the principles of design patterns are the same regardless the language. So let's keep it language agnostic – Thomas Apr 28 '13 at 20:21
-1

Separation of concerns is key here. With that said, your Controller shouldn't be aware of form data. In fact, a Controller needn't have any notion of html forms at all.

Your Model should encapsulate what values you intend on supplying via some form. Your Controller performs operations on the Model (e.g. loading data from your Model to a database).

Each MVC framework will be slightly different in what conventions are used, but in a general sense, what I've said above shoukd hold true for any MVC framework.

Update (in response to your comment):

No, the opposite of that. Your form data should be encapsulated by a Model/View Model which is passed to a Controller, which inserts/updates your underlying data store (i. e. your database). Think of MVC as a highway road system. Your Models are cars that drive along the paths, and the Controllers direct the traffic. Models are typically simple objects that house data fields, and Controllers do things with that data. Models/View Models are separate from your database data; Models are what you're willing to present to your Views (the presentation layer). Your database is a separate layer/tier from your Views/Models/Controllers, although your Controller is responsible for translating Models into your underlying database.

Didaxis
  • 8,486
  • 7
  • 52
  • 89
  • So the Controller passes the data to the Form Model, which does all the processing and creates the User right? – Thomas Apr 28 '13 at 16:44
  • See the update to my answer, couldn't fit all that into a comment. – Didaxis Apr 28 '13 at 17:13
  • 1
    The above is not MVC. I'm not even sure it is MVVM. The controller inserts/updates nothing in the database. That is what the persistence layer of the model is for. – PeeHaa Apr 28 '13 at 18:20