`

惯例优先原则

 
阅读更多
13.11. 惯例优先原则(convention over configuration)
引自http://www.iteedu.com/webtech/j2ee/spring25cn/ch13s11.php
对于很多项目来说,严格遵从已有惯例和使用合理的缺省选项大概是这些项目需要的……现在Spring Web MVC明确的支持了这种惯例优先原则的主旨。 这意味着,如果建立了一套命名规范,诸如此类,就可以显著地减少系统所需配置项目的数量, 来建立处理器映射、视图解析器、ModelAndView实例,等等。 这为快速原型开发提供了很大方便。同时提供了一定程度的(通常是好事情)代码库的一致性,进而可以从中选择并发展为成型产品。
提示

Spring分发版本包含了一个展现了惯例优先原则支持的Web应用程序,我们将在这一节描述这一原则。 这个应用程序可以在samples/showcases/mvc-convention目录中找到。
惯例优先原则支持体现在MVC的三个核心领域:模型、视图和控制器。
13.11.1. 对控制器的支持:ControllerClassNameHandlerMapping

ControllerClassNameHandlerMapping类是HandlerMapping接口的一个实现。 它使用惯例来确定请求的URL和用于处理它们的Controller实例间的映射关系。
举个例子,考虑下面的(直观的)Controller实现, 请特别注意这个类的名称。
public class ViewShoppingCartController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
        // the implementation is not hugely important for this example...
    }
}
下面是与之伴随的Spring Web MVC配置文件的一个片段:
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
               
<bean id="viewShoppingCart" class="x.y.z.ViewShoppingCartController">
    <!-- inject dependencies as required... -->
</bean>
ControllerClassNameHandlerMapping在它的应用上下文中找出所有不同的处理器(handler)(或Controller)bean, 并去掉名称中的Controller,来定义它的处理器映射。
让我们看更多的例子,这样其中的中心思想就马上就清楚了。
WelcomeController映射到“/welcome*”请求URL
HomeController映射到“/home*”请求URL
IndexController映射到“/index*”请求URL
RegisterController映射到“/register*”请求URL
DisplayShoppingCartController映射到“/displayshoppingcart*请求URL
(注意大小写——全部小写——对于驼峰式大小写(第一个词的首字母小写,随后的每个词首字母大写)的Controller类名。)
当控制器是MultiActionController处理器类时,生成的映射就(有一点点)更为复杂,但幸而没有更难理解。 下面例子中的几个Controller名字假设都是MultiActionController的实现。
AdminController映射到“/admin/*”请求URL
CatalogController映射到“/catalog/*”请求URL
如果遵循漂亮而且标准的规范把你的Controller实现命名为xxxController, 那么ControllerClassNameHandlerMapping将使你免于忍受必须首先定义它们, 然后还要维护冗——长——的——SimpleUrlHandlerMapping(或者类似的东西)的枯燥。
ControllerClassNameHandlerMapping是AbstractHandlerMapping的子类, 从而使你能够像对待大量其他HandlerMapping实现一样的定义HandlerInterceptor实例和其他任何东西。
13.11.2. 对模型的支持:ModelMap(ModelAndView)

ModelMap类首先是一个绚丽的Map实现, 它可以使新增的将要显示在View中(或上)的对象也遵循同一命名规范。 考虑下面的Controller实现,注意对象被加入ModelAndView, 而并没有指定任何名称。
public class DisplayShoppingCartController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
       
        List cartItems = // get a List of CartItem objects
        User user = // get the User doing the shopping
       
        ModelAndView mav = new ModelAndView("displayShoppingCart"); <-- the logical view name

        mav.addObject(cartItems); <-- look ma, no name, just the object
        mav.addObject(user); <-- and again ma!

        return mav;
    }
}
ModelAndView类使用的ModelMap类是一个自定义的Map的实现。 当有一个新对象加入的时候,它就被用于为这个对象自动生成一个键。 决定某个加入的对象的名字的策略是,当它是一个标量对象(scalar object),比如User时, 就使用这个对象所属类的简短类名。下面的几个例子中,几个为标量对象生成的名字被加入ModelMap实例中。
将会为一个新增的x.y.User实例生成“user”作为名称
将会为一个新增的x.y.Registration实例生成“registration”作为名称
将会为一个新增的x.y.Foo实例生成“foo”作为名称
将会为一个新增的java.util.HashMap实例生成“hashMap”作为名字(在这个情形下你可能想要让名字更加明确一些,因为“hashMap不太直观)。
新增null将会导致抛出一个IllegalArgumentException。 如果正在加入的这个(或这些)对象可能潜在的是null的话,就要让名字更明确一些。
什么?不能自动生成复数?
Spring Web MVC的惯例优先原则的支持内容中不包括自动生成复数。 这就是说,当加入一个Person对象的List到一个ModelAndView时, 不要指望生成的名字会是“people”。
这是经过一系列讨论之后作出的决定,最后“最小惊讶原则(Principle of Least Surprise)”胜出。
在加入一个Set、List或者对象数组之后, 生成名称的策略是深入这个集合,取出集合中第一个对象的简短类名,并使用这个名称并在后面加上List。 一些例子将会让集合的名称生成方式更清晰……
将会为一个新增的包含了一个或多个x.y.User元素的x.y.User[]实例生成“userList”作为名称
将会为一个新增的包含了一个或多个x.y.User元素的x.y.Foo[]实例生成“fooList”作为名称
将会为一个新增的包含了一个或多个x.y.User元素的java.util.ArrayList实例生成“userList”作为名称
将会为一个新增的包含了一个或多个x.y.Foo元素的java.util.HashSet实例生成“fooList”作为名称
一个空java.util.ArrayList根本不会被加入(也就是说,addObject(..)调用其实什么都没做)。
13.11.3. 对视图的支持:RequestToViewNameTranslator

RequestToViewNameTranslator接口的功能是当没有显式的提供这样一个逻辑视图名称的时候, 确定一个逻辑的View名称。 这个接口只有一个实现,精明的命名为DefaultRequestToViewNameTranslator。
为了解释DefaultRequestToViewNameTranslator将请求的URL映射到逻辑的视图名的方式, 最好还是求助于一个例子。
public class RegistrationController implements Controller {
               
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
        // process the request...
        ModelAndView mav = new ModelAndView();
        // add data as necessary to the model...
        return mav;
        // notice that no View or logical view name has been set
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

    <!-- this bean with the well known name generates view names for us -->
    <bean id="viewNameTranslator" class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator"/>

    <bean class="x.y.RegistrationController">
        <!-- inject dependencies as necessary -->
    </bean>
   
    <!-- maps request URLs to Controller names -->
    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>
请注意,在这个handleRequest(..)方法的实现中, 没有在返回的ModelAndView上设置任何的View或者逻辑视图名称。 而是把从请求的URL生成一个逻辑视图名称的任务交给了DefaultRequestToViewNameTranslator。 在上面这个RegistrationController与ControllerClassNameHandlerMapping联合使用的例子中, 一个“http://localhost/registration.html”请求URL将会由DefaultRequestToViewNameTranslator生成一个“registration”逻辑视图名称。 这个逻辑视图名称接下来就会被InternalResourceViewResolver bean解析为“/WEB-INF/jsp/registration.jsp”视图。
提示

甚至不需要显式的定义一个DefaultRequestToViewNameTranslator bean。 如果DefaultRequestToViewNameTranslator的缺省设置符合你的要求, 就可以依赖这样一个事实,Spring Web MVC的DispatcherServlet将会在没有显式配置的情况下自动的生成这个类的一个实例。
当然,如果需要修改缺省设置,那么就需要显式的配置自己的DefaultRequestToViewNameTranslator bean。 关于可以设置的各种属性的细节,请参阅DefaultRequestToViewNameTranslator的相当详细的Javadoc。
分享到:
评论

相关推荐

    JavaEE 6 Servlet 3.0 中的新特性

    JavaEE 6Servlet 3.0 中的新特性 • 易于开发和部署 • 模块化web.xml • 动态配置 • 异步Servlet • Servlet 3.0 — 易于开发 ...• 惯例优先原则(Convention over) – 更好的默认值 – 例外配置

    SPRING入门

    Spring MVC介绍 Spring MVC属于springFrameWork(spring)的产品,它是基于java的轻量级web框架,使用MVC架构模式,将web层进行解耦功能,前端控制器是...提供了强大的约定大于配置(惯例优先原则)的契约式编程支持

    springmvc demo

    Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动...提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。

    spring chm文档

    13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持: ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap (ModelAndView) 13.11.3. 对视图的支持: ...

    Spring中文帮助文档

    13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持:ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap(ModelAndView) 13.11.3. 对视图的支持:...

    Spring 2.0 开发参考手册

    13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持: ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap (ModelAndView) 13.11.3. 对视图的支持: ...

    Spring API

    13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持:ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap(ModelAndView) 13.11.3. 对视图的支持:...

    Spring-Reference_zh_CN(Spring中文参考手册)

    13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持: ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap (ModelAndView) 13.11.3. 对视图的支持: ...

    Ruby on Rails Web开发之旅.pdf【第二部分】

    1.2.1 惯例优先 1.2.2 不重复自我 1.2.3 灵活的开发 1.3 构建wleb应用程序示例 1.3.1 digg简介 1.3.2 应用程序示例的特性 1.4 小结 第2章 技术准备  2.1 所需软件的成本  2.2 在Windows系统上安装Ruby on Rails ...

    Ruby on Rails Web开发之旅.pdf【第一部分】

    1.2.1 惯例优先 1.2.2 不重复自我 1.2.3 灵活的开发 1.3 构建wleb应用程序示例 1.3.1 digg简介 1.3.2 应用程序示例的特性 1.4 小结 第2章 技术准备  2.1 所需软件的成本  2.2 在Windows系统上安装Ruby on Rails ...

    Ruby on Rails Web开发之旅.pdf【第三部分】

    1.2.1 惯例优先 1.2.2 不重复自我 1.2.3 灵活的开发 1.3 构建wleb应用程序示例 1.3.1 digg简介 1.3.2 应用程序示例的特性 1.4 小结 第2章 技术准备  2.1 所需软件的成本  2.2 在Windows系统上安装Ruby on Rails ...

Global site tag (gtag.js) - Google Analytics