Controller 是 Spring 中最基本的组件,主要处理用户交互,一般每个业务逻辑都会有一个 Controller,供用户请求接口进行数据访问;@RequestMapping 注解用于绑定URI到具体处理器。二者相辅相成,共同完成前后端数据交互。

一、简介

       本文软件环境:
IntelliJ IDEA version:2018.3
Spring Boot version: 2.1.4.RELEASE;
Java version:1.8。

Controller 是 Spring 中最基本的组件,主要处理用户交互,一般每个业务逻辑都会有一个 Controller,供用户请求接口进行数据访问。

        在Spring MVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。Spring MVC 提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类即可,然后使用@RequestMapping 和@RequestParam 等一些注解以定义URL 请求和Controller 方法之间的映射,这样Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象。
        @RequestMapping 注解可谓非常的强大,Spring MVC 和 Spring Boot 中都会用到这个注解。要学会 @RequestMapping 的用法,就需要从它的原理和实现机制说起,本文就和读者朋友们一起扒一扒Spring Boot中 @RequestMapping 的神秘面纱。
为了先对Controller 有一个初步的印象,我们定义一个简单的UserController:
       例1 控制器类UserController
@Controller
@RequestMapping("/user")
public class UserController {
private static Logger logger = LoggerFactory.getLogger(UserController.class);
/**
* 示例地址 http://localhost:8087/user/viewUser?ownerId=100
*
* @author Wiener
* @date 2019/5/8 11:27
*/
@RequestMapping("/viewUser")
    @ResponseBody
public User viewUser(Long ownerId) {
logger.info("请求参数 ownerId = " + ownerId);
User user = new User();
user.setId(ownerId);
user.setName(" --> Lucy");
return user;
}
}
// 定义User Bean
public class User {
private Long id;
private String name; // omit getter、setter and toString
}

在上述示例中,@Controller 是标记在类UserController上面的,所以此类就是一个控制器类对象了。使用@RequestMapping("/user")标记控制器,用@RequestMapping(“/viewUser”) 标记方法,表示当请求“/user/viewUser”的时候访问的是UserController的viewUser方法,它返回了一个User 对象。这些在下文将会详细介绍。

二、@RestController介绍

        在例1中,被@Controller标记的类就是一个Spring Boot Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。@Controller只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器,这个接下来就会讲到。
在Spring Boot Web项目中,单单使用@Controller 标记在一个类上就可以把这个控制器类交给Spring 来管理,无需额外配置。
       @RestController:Spring 4 新增注解,同样可以注解 Controller 类,相当于@Controller + @ResponseBody,主要是为了使 http 请求返回 json 或者xml格式数据,一般情况下都是使用这个注解。下文都基于此注解进行验证。

三、@RequestMapping 配置URI映射

        要配置 Web 请求的映射,就需要用上 @RequestMapping 注解。@RequestMapping 注解可以在控制器类的级别和/或其中的方法的级别上使用。在类级别上的注解会将一个特定请求或者请求模式映射到一个控制器之上,之后还可以添加方法级别的注解来进一步绑定与具体处理方法的映射关系。类上的 “请求地址”是方法上的“请求地址”的父地址。
        在例1中,因为UserController被@RequestMapping 标记,所以当访问被@RequestMapping 标记的viewUser方法时,需要使用相对路径“/user/viewUser”请求;如果去掉“/user”,使用绝对路径“/viewUser”就可以了。
       @RequestMapping 注解的源码:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
String[] value() default {};
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}

注解@Target有两个属性,分别为 ElementType.METHOD 和 ElementType.TYPE,这表明@RequestMapping注解可以添加在类级别和方法级别上。

     @RequestMapping 注解中的属性除了 name 返回类型是字符串,其它的方法均返回数组,也就是可以定义多个属性值。此处name属性,相当于方法的注释,使方法更易理解。

四、@RequestMapping属性介绍

        在RequestMapping 中除了指定请求路径value 属性外,还有其它的属性可以指定,如params 、method 和headers 。这些属性都可以达到缩小请求的映射范围的目的。
  1. value属性
        指定request的地址。在例1中,value="/viewUser",使用了value的简写方式。
        value 属性支持有占位符的路径,此时需要结合@PathVariable注解,详见《注解之@PathVariable》。
        value 属性支持ANT风格的路径。
        例2 ANT风格的路径和多URI配置
@RestController@RequestMapping("/home")
public class IndexController {
@RequestMapping(value = {
"",
"/page",
"page*",
"view/*,**/msg"
})
String indexMultipleMapping() {
return "Hello from index multiple mapping.";
}
}

前面这段代码中,如下的这些 URI 都会由 indexMultipleMapping() 来处理:

localhost:8080/home
localhost:8080/home/page
localhost:8080/home/pageabc
localhost:8080/home/view/
localhost:8080/home/view/view
localhost:8080/home/view2/msg

这个示例同时说明了可以将多个请求映射到一个方法上去,只需要添加一个带有请求路径值列表的 @RequestMapping 注解就行了。

  1. params属性
        用于定义请求的 URL 中必须包含的参数,或者不包含某些参数。
       例3 限定@RequestMapping 的params属性
@RequestMapping (value= "/testParams" , params={ "param1=value1" , "param2" , "!param3" })
public String testParams() {
System. out .println( "test Params..........." );
return "testParams" ;
}

在上面的代码中,我们用@RequestMapping 的params 属性指定了三个参数,这些参数都是针对请求参数而言的,它们分别表示参数param1 的值必须等于value1,param2 必须存在,值无所谓,param3 必须不存在,只有当请求“/testParams”并且满足指定的三个参数条件的时候才能访问到该方法。所以当请求/testParams?param1=value1&param2=value2 的时候testParams函数能够正确响应;当请求/testParams?param1=value1&param2=value2&param3=value3 的时候就无响应,因为在@RequestMapping 的params 参数里面指定了参数param3 是不能存在的。

  1. method属性
        属性类型包括GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE和TRACE等八种。可以为多个方法映射相同的URI,Spring MVC 根据请求的 method 类型识别这些方法。若是没指定method,则它可以处理method任何类型的请求,此时它的映射范围是最大的。指定 method 是为了细化映射,缩小处理方法的映射范围。在例1中,函数viewUser可以响应get和post等请求。
        例4 设置get和delete请求
@RequestMapping (value= "testMethod" , method={RequestMethod. GET , RequestMethod. DELETE })
public String testMethod() {
return "method" ;
}

在上面的代码中就使用method 参数限制请求方式,以GET 或DELETE 方法请求/testMethod 的时候才能访问testMethod 方法。

  1. headers属性
        用 myHeader = myValue 这样的格式指定 header 元素的值。
       例5 header 属性
    @RequestMapping (value= "testHeaders" , headers={ "host=localhost" , "Accept" })
public String testHeaders() {
return "headers" ;
}

在上面的代码中当请求/testHeaders 的时候只有当请求头包含Accept 信息,且请求的host 为localhost 的时候才能正确的访问到testHeaders 方法。

  1. produces和consumes属性
        用来限定请求的媒体类型,二者用法类似,下面以consumes属性为例。此测试用例仅仅可以同时处理post请求中的 JSON 和 XML 内容。
       例6 consumes属性
    @PostMapping(value = "/cons", consumes = {
"application/JSON",
"application/XML"
})
public User getConsumes(Long ownerId) {
User user = new User();
user.setId(ownerId);
user.setName("Consumes attribute --> Lucy");
return user;
}

Reference

注解之 @RestController 和 @RequestMapping的更多相关文章

  1. SpringBoot中常用注解@Controller/@RestController/@RequestMapping的区别

    @Controller 处理http请求 @Controller //@ResponseBody public class HelloController { @RequestMapping(valu ...

  2. SpringBoot 中常用注解@Controller/@RestController/@RequestMapping的区别

    SpringBoot中常用注解@Controller/@RestController/@RequestMapping的区别 @Controller 处理http请求 @Controller //@Re ...

  3. SpringBoot 中常用注解@Controller/@RestController/@RequestMapping介绍

    原文 SpringBoot 中常用注解 @Controller/@RestController/@RequestMapping介绍 @Controller 处理http请求 @Controller / ...

  4. springmvc常用注解之@Controller和@RequestMapping

    对于各种注解而言,排第一的当然是“@Controller”,表明某类是一个controller. “@RequestMapping”请求路径映射,如果标注在某个controller的类级别上,则表明访 ...

  5. 【#】Spring3 MVC 注解(二)---@RequestMapping

    博客分类:  spring MVC  1 问题:有多个 @RequestMapping @controller @RequestMapping("/aaa")           ...

  6. Spring Boot常用注解总结

    Spring Boot常用注解总结 @RestController和@RequestMapping注解 @RestController注解,它继承自@Controller注解.4.0之前的版本,Spr ...

  7. SSM框架主要几个注解的位置

    @Controller @Service @Repository @Component Controller (控制层) Service (业务层) daoImpl (实现层) 模糊注解 @Autow ...

  8. 前端-关于CORS跨域的解决方案,面向服务端

    最近自己在写后台管理系统的时候,并没有采用jsp.freemaker.叶子等模板技术,而是由后端提供数据api,前端通过AJAX和JQuery来动态操作页面上的一些div.table元素,从而实现报表 ...

  9. 超详细 Spring @RequestMapping 注解使用技巧

    @RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一.这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上. 在这篇文章中,你将会看到 @R ...

随机推荐

  1. 十六进制转换十进制(JAVA版)

    解题思路路大概为:现将十六进制数转换为二进制数,再讲二进制数转换为八进制数.在进行十六进制转换为八进制时可以利用JAVA中的‘&’运算符号,一个十六进制数可以表示为四个二进制数,利用‘& ...

  2. 基于【 centos7】四 || FastDFS集群+Nginx负载均衡

    1. 架构设计 1.1 架构图 FastDFS是用c语言编写的一款开源的分布式文件系统.FastDFS为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使用F ...

  3. vue购物车动画效果

    使用动画的三个函数 v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter=&q ...

  4. vue——store全局存储

    业务场景:刷新页面时,首次拉取所有配置,存储到store状态管理用于全局调用: import Vue from 'vue' import Vuex from 'vuex' import userInf ...

  5. Image Processing and Analysis_15_Image Registration:Mutual-Information-Based Registration of Medical Survey——2003

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  6. 搭建KVM环境——07 带GUI的Linux上安装KVM图形界面管理工具

    清空yum源缓存,并查看yun源 [root@CentOS2 ~]# yum clean all Loaded plugins: fastestmirror, langpacks Cleaning r ...

  7. [杭电oj][1005]Number Sequence

    sky同学在努力地刷题..,在这题卡住了,于是一起研究了一下... 这题本身挺简单的,(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) m ...

  8. 【转】ufw 端口

    1.扫描端口 用ubuntu自带的网络工具中的端口扫描不够强大,扫描结果可能不全,推荐用nmap,黑客常用的端口扫描利器!安装方法:sudo apt-get install nmap ,想扫描端口nm ...

  9. 2018年5月20日--西安icpc邀请赛试题一览

    热身赛 正式赛 A题,样例不代表后台数据,出题人把题意和后台数据代表的意思搞差了! B: C: D-E F f-G G G-H H-I I-J J-k K-2

  10. 通过Java调用Python脚本

    在进行开发的过程中,偶尔会遇到需要使用Java调用Python脚本的时候,毕竟Python在诸如爬虫,以及科学计算等方面具有天然的优势.最近在工作中遇到需要在Java程序中调用已经写好的Python程 ...