将视图代码放在控制器中是不好的做法?

时间:2009-09-01 18:09:14

标签: java spring jsp java-ee model-view-controller

在MVC(例如JSP和Spring)中,在控制器中查看相关代码是不好的做法?

在我的情况下,控制器完成一些工作,然后将结果移交给视图(JSP)。对于状态消息,我可以将整个消息文本传递给视图,或者传递一个键,让JSP将其映射到消息文本。

示例:

在控制器中生成的消息

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}

在视图中生成的消息

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>

在第一种情况下,控制器和JSP代码更简单,但控制器中存在与视图相关的逻辑。 在第二种情况下,所有视图逻辑都在JSP中,但代码并不那么简单。

我是否通过在控制器中生成消息文本来违反MVC范例?这种情况的常见做法是什么?

3 个答案:

答案 0 :(得分:6)

通常的做法是使用资源包:-)您可以在Spring上下文中将它们配置为message sources,并使用message标记来检索它们。

答案 1 :(得分:3)

在MVC中组合UI和Controller代码是Rich Clients中的常见做法(例如,在Swing中)。即使在Web MVC中,它也有时会实现,只需要非常简单的响应。

在你的情况下,不建议你做什么。通常,您使用spring的resource bundle机制将应用程序的文本放在MessageSource中,并仅使用代码引用它。资源包是一个简单的属性文件,在您的情况下它将如下所示:

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

在JSP中,您使用标记以下列方式引用它:

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

资源包有两个优点:

  • 您的网站很容易国际化并以多种语言提供
  • 您可以在源外部管理应用程序文本,如果使用spring ReloadableResourceBundleMessageSource,您甚至可以在不重新部署应用程序的情况下更改文本。

答案 2 :(得分:0)

我不认为这是不好的做法。决定是在视图中还是在控制器中放置一些逻辑的一个好策略是想象一下你会有两个不同的视图引擎的场景。然后,您可以检查两个视图引擎中是否不会重复该特定代码。

例如,假设你有一个相同的控制器,但是另一个视图渲染器,比如一个生成Excel电子表格的渲染器。

在您的示例中,您必须将检索正确消息的逻辑放在JSP(呈现HTML)中,而且还放在Excel电子表格中(作为公式)。

总而言之,您给出的示例表示视图不可知的逻辑,因此控制器是它的好地方。

例如,它不适用于决定特定文本是否应该呈现为粗体的逻辑。这是视图特定的逻辑。 HTML使用sylesheets呈现粗体文本,而其他视图引擎使用不同的表示。在这种情况下,保持这种逻辑的最佳位置是视图层(用于HTML视图的JSP等)