views:

246

answers:

3

In MVC (such as JSP and Spring), is it bad practice to view related code in the controller?

In my case, the controller does some work and then hands off the results to the view (JSP). In the case of a status message, I can pass the entire message text to the view, or pass a key and let the JSP map it to the message text.

Example:

Message generated in controller

Spring Controller:

protected ModelAndView onSubmit(...) {
    Map map = new HashMap();
    // Controller processing
    if (...)
        map.put("status", "Case 1 status message");
    else
        map.put("status", "Case 2 status message");
    return new ModelAndView("viewPage", map);
}

JSP:

{$status}

Message generated in view

Spring Controller:

protected ModelAndView onSubmit(...) {
    Map map = new HashMap();
    // Controller processing
    if (...)
        map.put("status", "case1");
    else
        map.put("status", "case2");
    return new ModelAndView("viewPage", map);
}

JSP:

<c:choose>
  <c:when test="{$status eq 'case1'}">Case 1 status message</c:when>
  <c:when test="{$status eq 'case2'}">Case 2 status message</c:when>
</c:choose>

In the first case, the controller and JSP code is simpler, but there's view related logic in the controller. In the second case, all view logic is in the JSP, but the code isn't as simple.

Am I violating MVC paradigm by generating message text in the controller? What is the common practice for this scenario?

+6  A: 

The common practice is to use resource bundles :-) You can configure them as message sources in your Spring context and use message tag to retrieve them.

ChssPly76
+1 - I like how you didn't just say yes or no, but gave a nice suggestion that would be an improvement, as it also gives more flexibility.
James Black
+3  A: 

Combining UI and Controller code in MVC is common practice in Rich Clients (in Swing for example). even in web MVC it is sometimes implemented, for very simple responses.

In your case however what you are doing is not recommended. Usually you put the texts of your application in a resource bundle using spring's MessageSource mechanism, and refer to it only using codes. The resource bundle is a simple properties file, in your case it will look like this:

case1=Case 1 status message
case2=Case 2 status message

In the JSP you refer to it using the tag in the following manner:

<spring:message message="${status}"/>

Resource bundles have two advantages:

  • It is easy to internationalise your site and provide it in multiple languages
  • You can manage the application texts externally to the source, and if you use spring's ReloadableResourceBundleMessageSource you can even change the texts without re-deploying the application.
David Rabinowitz
A: 

I don't think it is bad practice. One good strategy to decide whether to put some logic in the view or in the controller would be to imagine a scenario where you would have two different view engines. Then you may check if that particular code wouldn't be repeated in the two view engines.

For example, let's say that you had the same controller, but an alternative view renderer, let's say, a renderer that generates an Excel spreadsheet.

In your example you would have to place the logic of retrieving the correct message not only in the JSP (that renders HTML), but also in the Excel spreadsheet (as a formula).

To summarize, the example you gave represents logic that is view agnostic therefore the controller is good place for it.

It wouldn't apply for a logic, for example, that decides if a particular text should be rendered as bold or not. This is view specific logic. HTML uses sylesheets to render bold text whereas other view engine uses a different representation. In that case the best place to hold this logic would be the view layer (JSP for HTML views and etc.)

Daniel Melo