相比传统的继承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. JS去除空格方法记录

    JS中去掉空格 //去除空格  String.prototype.Trim = function() {      return this.replace(/\s+/g, ""); ...

  2. 从 github 上 fork repositories 后,如何和原仓库同步?

    1. 首先要先确定一下是否建立了主repo的远程源: git remote -v 2. 如果里面只能看到你自己的两个源(fetch 和 push),那就需要添加主repo的源: git remote ...

  3. (二十一)WebGIS中鹰眼的实现思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 鹰眼功能是WebGIS中的一种常见功能,利用一些开源的框架实现 ...

  4. 常用查找数据结构及算法(Python实现)

    目录 一.基本概念 二.无序表查找 三.有序表查找 3.1 二分查找(Binary Search) 3.2 插值查找 3.3 斐波那契查找 四.线性索引查找 4.1 稠密索引 4.2 分块索引 4.3 ...

  5. 20 个看起来很棒的 Web UI 工具包

    程序员们比设计师更需要这些 UI 方面的内容: 1. Mini Reminders Mini Reminders 2. Transluscent UI elements Transluscent UI ...

  6. jQuery插件之ajaxFileUpload异步上传

    介绍 AjaxFileUpload.js 是一个异步上传文件的jQuery插件,原理是创建隐藏的表单和iframe然后用JS去提交,获得返回值. 下载地址: http://files.cnblogs. ...

  7. CCF——Z字形扫描问题

    试题编号: 201412-2 试题名称: Z字形扫描 时间限制: 2.0s 内存限制: 256.0MB 问题描述: 问题描述 在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag ...

  8. Linux基础知识之文件和目录的权限机制

    Linux中的用户 Linux中的用户有三类,分别是: 所有者(u) 同组用户(g) 其他人(o) 如下图所示,假设存在两个组:groupA和groupB,rachel和ross属于组groupA,m ...

  9. ActiveX(四) mshtml 命名空间 重要接口简介

    在上一篇随笔 ActiveX(三)ActiveX 调用 Js 中,我们已经可以获得js中window对象的强类型接口.即 mshtml.IHTMLWindow2 ,通过该接口.我们可以调用js函数.那 ...

  10. jQuery实现方式不一样的跳转到底部

    jQuery跳转到页面底部效果 在线体验:http://hovertree.com/texiao/jquery/9.htm 以下是完整HTML代码: <!DOCTYPE html> < ...