相比传统的继承Controller体系中某些类的方式,SpringMVC的注解具有以下优点: 1、Controller不再需要继承某个特定类,只是简单的POJO。 2、请求映射的配置非常方便灵活。 3、参数绑定机制非常方便丰富。 4、可以根据不同的http方法或者参数,细粒度处理不同的http请求

一、概述

SpringMVC在2.5版本后新增了注解功能,2.5版本以前的基本通过继承Controller体系来开发业务控制器,2.5版本后Controller体系中 BaseCommandController及其子类AbstractCommandController、AbstractFormController、AbstractWizardFormController、

SimpleFormController、CancellableFormController等都已经被标示为@Deprecated,建议不再使用。

相比传统的继承Controller体系中某些类的方式,SpringMVC的注解具有以下优点: 1、Controller不再需要继承某个特定类,只是简单的POJO。 2、请求映射的配置非常方便灵活。 3、参数绑定机制非常方便丰富。 4、可以根据不同的http方法或者参数,细粒度处理不同的http请求

二、示例

下面通过对SpringMVC注解的详细介绍来看一下上述优点。
首先需要在应用的dispatcher-servlet.xml 启动注解机制

<context:annotation-config /> <!-- 设置注解驱动 --> <mvc:annotation-driven />  <!-- 设置扫描的包 --> <context:component-scan base-package="com.demo.web.controller" /> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

注:虽然我们的Controller不需要再继承任何类,但出于规范,我们仍然命名为***Controller.java,并统一放在com.demo.web.controller包中。

1、@Controller注解

简单示例 下载地址

package com.demo.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;
@Controller class IndexController {     @RequestMapping("/index")     String index() {         return "index";     } }

在一个POJO上面使用 @Controller 就可以标注该POJO是一个Controller,就这么简单。 @Controller注解定义在org.springframework.steretype包中。 使用方式: @Controller 或者 @Controller("indexController)。 org.springframework.steretype包中还包含 @Componenet @Service @Respository 三个注解。@Component是通用标注,@Controller标注web控制器,@Service标注Servicec层的服务,@Respository标注DAO层的数据访问。

2、使用@RequestMapping注解处理请求映射

SpringMVC中注解基本都包含在 org.springframework.web.bind.annotation 包中。先看一下@RequestMapping 注解的源码。

@Target( { ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping public @interface RequestMapping {
    /**      * 指定映射的URL.可以在类层次和方法层次使用。方式如下:      * @RequestMapping("/add_")或 @RequestMapping(value = "/add")      * 支持Ant风格的URL映射,如 @RequestMapping("/myPath/*.htm")      * 在类层次指定了映射后,可以在方法层次再指定相对路径      */     String[] value() default {};
    /**      * 指定HttpRequest的方法, 如:GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.      * 使用举例: @RequestMapping(value = "/add_activity", method = RequestMethod.GET)      */     RequestMethod[] method() default {};
    /**      * 指定HttpRequest中包含的参数,使用方式如下:      * @RequestMapping(value = "/something",params="myParam") 请求包含myParam参数      * @RequestMapping(value = "/something",params="myParam=myValue")请求包含myParam参数,并且该参数值为myValue      * @RequestMapping(value = "/something",params="!myParam") 请求不包含myParam参数      */     String[] params() default {};
    /**      * 指定HttpRequest中包含的头部信息,使用方式如下:      * @RequestMapping(value = "/something", headers="content-type")请求包含该头部      * @RequestMapping(value = "/something", headers="content-type=text/*")请求包含特定值的头部      * @RequestMapping(value = "/something", headers="!content-type")请求不包含该头部      */     String[] headers() default {};
}

注:如果在类层次指定了映射,则方法层次上都将继承类层次的映射

3、下载地址 获取HttpRequest中得参数

@RequestMapping("active") public @ResponseBody boolean active(Long accountId) {     return accountService.activeAccount(accountId); }

@RequestMapping("active") public @ResponseBody boolean active(Account account) {     return accountService.activeAccount(accountId); }

@RequestMapping("inactive") public @ResponseBody boolean inactive(@RequestParam("accountId") Long accountId,             @RequestHeader("User-Agent") String userAgent,             @CookieValue("loginId") String loginId) {     return accountService.inactiveAccount(accountId); }
@RequestMapping(value = "list/{pageNo}", method = RequestMethod.GET) public String list(@PathVariable int pageNo) {      return "/account/list"; }

@RequestMapping(value = "add", method = RequestMethod.GET) public String add(@RequestBody String body) {      return "/account/add"; }

active方法的入参 accountId,如果请求中有名为 accountId的参数,则会进行默认绑定,不仅基本类型,javabean的属性也可以默认进行绑定; 如果需要明确绑定,使用@RequestParam。 一般建议进行明确指定。

3.1 @RequestParam 绑定httpRequest中参数,@RequestParam("accountId") 完整形式为  @RequestParam(value="accountId",required=true,defaultValue=null) 3.2 @RequestHeader 绑定httpRequest头部信息,@RequestHeader("User-Agent") 完整形式为 @RequestHeader(value="User-Agebt",required=true, defaultValue=null) 3.3 @CookieValue 绑定一个Cookie值,@CookieValue("loginId") 完整形式为 @CookieValue(value="loginId",required=true,defaultValue=null) 3.4 @RequestBody 将httpRequest的body绑定到方法参数上 3.5 @ModelAttribute 有两种使用方式: 1)在方法级别,指定方法的返回值绑定到model中; 2)方法参数级别,指定model中的值绑定到方法的入参上 示例如下:

@ModelAttribute("countryList")     public List<String> getCountries() {         return new ArrayList<String>();     }
@RequestMapping(value = "search", method = RequestMethod.POST)     public String searchAccount(@ModelAttribute("accountId") Long accountId) {         return "/search";     }

4、使用@ResponseBody 生成response

适用于webservice的数据交换,或ajax异步请求,text、json或者xml格式的数据交换。     例如访问: http://localhost:8080/accounts/info.htm

@RequestMapping(value = "info") public @ResponseBody Account getAccount() {         Account a = new Account();         a.setId(123L);         a.setName("zhangsan");         return a;  }

返回数据如下下载地址 :

{"name":"zhangsan","id":123}

从上面例子可以看出,使用@ResponseBody后,返回的javabean默认被序列化成json格式的数据并被写入到response body中。
@Request 和 @ReponseBody 使用了HttpMessageConverter机制。下面是HttpMessageConverter的继承体系。
常用的有如下几个:

StringHttpMessageConverter ---字符串

MappingJacksonHttpMessageConverter ----json

ByteArrayHttpMessageConverter ----字节数组

MarshallingHttpMessageConverter -----xml

5、使用模板技术生成response

适用于一般页面请求。可以使用velocity freemarker等模板技术,在dispatcher-servlet.xml中需要设置viewResolver。

@RequestMapping("/index") public String index(ModelMap modelMap) {         modelMap.put("name", "liucs");         return "index"; }
@RequestMapping("/index") public String index2(Model model) {         model.addAttribute("name","liucs");         return "index"; }

@RequestMapping("/index") public ModelAndView index3() throws Exception {       ModelAndView mav = new ModelAndView("index");       mav.addObject("name", "liucs");       return mav; }

如上面代码index1和index2所示,不使用@ResponseBody注解。 返回一个String类型,这个String是viewname, 如果是重定向,return "redirect:/index.htm". 入参可以包含ModelMap或者Model,其实这两者是一个东西,作用一样。也可以采用index3式的传统写法,返回一个ModelAndView对象。

6、数据验证

@InitBinder标注

@InitBinder     public void myInitBinder(WebDataBinder binder){       binder.setDisallowedFields(new String[]{"id"});     }

通过在方法中声明一个BindingResult参数来启动绑定和验证

@RequestMapping("update")     public void update(@ModelAttribute("account") Account account,BindingResult bindResult) {         if(bindResult.hasErrors()){             //……         }     }

需要注意以下限制: 1、BindingResult参数必须跟在一个JavaBean参数后面 2、错误会被自动的绑定到model中,便于渲染模板时使用 3、不支持@RequestBody等类型的参数形式

7、异常处理

@ExceptionHandler

基于注解的SpringMVC的更多相关文章

  1. SpringMVC札集(03)——基于注解的SpringMVC入门完整详细示例

    自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onL ...

  2. 基于注解的springmvc开发

    原理简析 1. 背景知识:org.springframework.web.ServletContainerInitializer接口 在基于注解的servlet开发中,ServletContainer ...

  3. 基于注解的SpringMVC简单介绍

    SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请 ...

  4. SpringMVC学习总结(四)——基于注解的SpringMVC简单介绍

    SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是 DispatcherServlet,DispatcherServlet负责转发每一个Request ...

  5. 【转载】基于注解的SpringMVC简单介绍

    SpringMVC是一个基于DispatcherServlet的MVC框架,每一个请求最先访问的都是DispatcherServlet,DispatcherServlet负责转发每一个Request请 ...

  6. Spring基于注解及SpringMVC

    1.使用注解 (1)组件扫描 指定一个包路径,Spring会自动扫描该包 及其子包所有组件类,当发现组件类定义前有 特定的注解标记时,就将该组件纳入到Spring 容器.等价于原有XML配置中的< ...

  7. 基于注解的SpringMVC整合JPA

    转载位置:http://www.blogjava.net/sxyx2008/archive/2010/11/02/336768.html 实体类 Department package com.sj.b ...

  8. spring in action 第五章基于注解搭建SpringMvc环境

    request的生命历程

  9. 02基于注解开发SpringMVC项目(jar包,异步,request,参数传递,多选的接收,Model传参,map传参,model传参,ajax,重定向,时间日期转换)

     1 所需jar包 项目结构如下: 2 web.xml配置文件的内容如下: <?xmlversion="1.0"encoding="UTF-8"?&g ...

随机推荐

  1. DotNet中几种常用的加密算法

    在.NET项目中,我们较多的使用到加密这个操作.因为在现代的项目中,对信息安全的要求越来越高,那么多信息的加密就变得至关重要.现在提供几种常用的加密/解密算法. 1.用于文本和Base64编码文本的互 ...

  2. Google数据中心B4网络具体实现

    ① 背景介绍 Google的网络有两种,一种是数据中心内部网络,另外一种是WAN网,其中WAN网又分为两种:一是数据中心之间的互联网络,属于内部网络(G-Scale Network),另外一种是面向I ...

  3. JAVA安全模型

    作为一种诞生于互联网兴起时代的语言,Java 从一开始就带有安全上的考虑,如何保证通过互联网下载到本地的 Java 程序是安全的,如何对 Java 程序访问本地资源权限进行有限授权,这些安全角度的考虑 ...

  4. C#基础知识四之override和new的区别

    override override是派生类用来重写基类方法的.调用的派生类方法,如需调用基类方法用base关键字 override不能重写非虚方法或静态方法. override重写必须用abstrac ...

  5. httpRuntime与ASP.NET 运行时及IIS处理模型

    配置 ASP.NET HTTP 运行时设置,以确定如何处理对 ASP.NET 应用程序的请求,配置节及其描述如下所示. <httpRuntime executionTimeout="1 ...

  6. 编辑IL文件 修改DLL文件

    本文章只是技术探讨,学习,技术上的研究而已.请支持正版. 如:KS.Gantt.DLL 为例 使用ILSpy反编译 工具 利用ildasm反编译 KS.Gantt.dll  生成IL中间代码 一般会生 ...

  7. input输入框提示语

    <input id="username" name="username" type="text" placeholder=" ...

  8. IOS 2D游戏开发框架 SpriteKit-->续(完善角色功能)

    一.说明       今天给角色精灵增加了子弹发射功能,增加了子弹与敌对精灵的碰撞检测,当角色精灵子弹与敌对精灵碰撞后,它们都会从屏幕上消失. 二.场景层SKScene的修改 1. 在初始化场景层的方 ...

  9. entityframework学习笔记--002-database first

    1.实体框架紧紧地和Visual Studio集成在一起,为了在你的应用程序中使用实体框架,我们增加一个ADO.NET实体数据框架到你的项目.方法如下: 右键你的项目,然后选择 ➤New Item(新 ...

  10. Linux下三个密码生成工具

    http://code.csdn.net/news/2820879 想出一个难破解且容易记的密码对不是一件简单的事情.在我为电脑设定一个新密码,或者在线注册了一个新的账号,需要输入密码的时候,脑袋就一 ...