- 浏览: 246305 次
-
文章分类
最新评论
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。
引自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。
发表评论
-
spring mvc 好的文档
2014-03-30 13:32 381http://jinnianshilongnian.iteye ... -
Spring dataSource配置
2012-11-12 14:32 715不管通过何种持久化 ... -
Spring MVC 3 深入总结
2012-07-24 15:24 830引自http://blog.csdn.net/sunitjy/ ... -
SpringMVC:整合JQUERY与JSON
2012-07-20 15:00 1339SpringMVC:整合JQUERY与JSON 引用别处 博客 ... -
基于Spring MVC的Web应用开发(3) - Resources
2012-07-17 14:12 1636基于Spring MVC的Web应用开发(3) - Resou ... -
Spring AOP 日志管理
2012-07-17 13:19 952Spring AOP http://blog.chinaun ... -
Spring AOP 日志管理
2012-07-17 13:18 0Spring AOP http://blog.chinau ...
相关推荐
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动...提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。
- **惯例优先原则**:为了进一步减少开发者的负担,Servlet 3.0 引入了惯例优先的原则,这意味着对于许多常见的配置项,框架会提供合理的默认值。开发者可以在必要时通过显式的配置来覆盖这些默认设置,从而确保应用...
13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持: ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap (ModelAndView) 13.11.3. 对视图的支持: ...
13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持:ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap(ModelAndView) 13.11.3. 对视图的支持:...
13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持: ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap (ModelAndView) 13.11.3. 对视图的支持: ...
13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持:ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap(ModelAndView) 13.11.3. 对视图的支持:...
13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持: ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap (ModelAndView) 13.11.3. 对视图的支持: ...
它不具有普遍性和全然性,不能等同于国家主权原则、平等互利原则、国际条约优先原则和国际惯例补缺原则这些基本冲突法原则。这些基本原则是指导中国冲突法制定和实施的核心,它们体现了国家主权、国际合作以及法律...
本原则强调设计要基于用户熟悉的概念和惯例。如果系统中的术语、操作流程或信息结构不符合用户的实际经验,用户在使用过程中就会感到不适应,难以理解系统的操作方式。例如,系统中的术语应该与用户日常生活中使用的...
此外,对通用条件的修改需明确标识,所有协议和谅解均需书面记录,并明确其在合同中的优先顺序。 **3. 黄金原则三(GP3):保留通用条件的基本平衡** GP3旨在保持合同双方风险与回报的平衡,不允许通过专用条件...
总之,《Qt编码标准与编程惯例修改稿2改_LiveWritter版》是Qt开发者的必备参考资料,它涵盖了从基础的编码风格到高级的设计原则,全面指导开发者写出高质量、易维护的Qt应用。通过深入学习并遵循这些标准,可以提高...
6. **及时转送**:根据伤员的伤情严重程度进行优先级排序,按照国际惯例进行转运,避免医疗资源的不合理分配。 7. **途中监护**:在转送过程中,持续监测伤员的生命体征,进行必要的急救措施,预防病情恶化。 以上...
首先,应纳税所得额计算的重要原则,又称为税法优先原则,意味着企业在计算所得税时,如果财务处理与税法规定不一致,应以税法为准。同时,税法未明确规定的部分,企业可遵循会计准则和惯例。在申报纳税时,会计利润...
在编程领域,堆栈是一种非常基础且重要的数据结构,它遵循“后进先出”(LIFO)的原则。本项目“堆栈实现的简单计算器”是利用堆栈来执行基本的算术运算,如加、减、乘、除。这个小程序对于理解数据结构,尤其是堆栈...
7. **国际惯例**:国际交往中形成的不成文原则和规则,如国际贸易中的信用证操作、UCP600等,属于国际惯例。 8. **国际经济法的基本原则**:国家主权原则、公平互利原则和国际合作以谋发展原则是国际经济法的基本...
在冲突情况下,合同条款优先于惯例。《中华人民共和国涉外经济合同法》进一步规定,国际条约和未作规定的法律空白可参照国际惯例。 国际贸易的产生和发展与社会生产力和分工密切相关。最初的国际贸易源于剩余产品的...
会计的国际化与国家化是现代会计领域的重要议题,这一议题主要关注在全球化背景下,如何平衡各国独特的会计理论和...通过理解会计特色、国际惯例和协调原则,我们可以更好地应对全球化的挑战,促进会计行业的健康发展。
4. 最小影响原则:系统漏洞加固工作应尽可能小的优先系统的正常运行,不能产生系统性能明显下降、网络拥塞、服务中断的情况。 5. 保密性原则:对加固过程中获知的任何信息都不得泄露给第三方或个人。 二、漏洞修复...
此外,契约性约束(如债权人要求和优先股协议)和其他因素(如市场环境、行业惯例)也会对利润分配产生影响。 股利理论是理解公司利润分配决策的关键。股利无关论,由莫迪格莱尼和米勒提出的MM理论,主张公司的价值...
在计算机科学中,栈是一种非常重要的数据结构,其遵循后进先出(LIFO, Last In First Out)的原则。栈通常用于解决需要“回溯”的问题,例如函数调用栈、括号匹配等问题。本文将详细介绍如何使用C语言中的栈来实现四...