详解 @RequestMapping 中的 consumes 和 produces

/ Java / 没有评论 / 1491浏览

详解 @RequestMapping 中的 consumes 和 produces

@RequestMapping 注解非常的强大,Spring MVC 和 SpringBoot 中都会用到这个注解。要学会 @RequestMapping 的用法,就需要从它的原理和实现机制说起。本文我们就一起来扒一扒 @RequestMapping 的神秘面纱。

@RequestMapping 是用来映射请求,可以配置在类上,也可以配置在方法上。说到映射请求,我们就应该想到 Servlet 在 web.xml 中的配置。

<servlet>
    <servlet-name>xttblog</servlet-name>
    <servlet-class>com.xttblog.XttblogController</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>xttblog</servlet-name>
    <url-pattern>/xttblog</url-pattern>
</servlet-mapping>

@RequestMapping 注解的作用就和上面的 web.xml 中配置 Servlet 映射的作用类似。

了解了 @RequestMapping 的作用,我们再来看看 @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 返回的字符串,其它的方法均返回数组,也就是可以定义多个属性值。

将 @RequestMapping 注解在方法上,而 Controller 上未添加 @RequestMapping 注解时,这时的请求 URL 是相对于 Web 根目录 /。

@RequestMapping 中的 method 主要用来定义接收浏览器发来的何种请求。使用枚举类 org.springframework.web.bind.annotation.RequestMethod 来定义浏览器请求的方式。我们常用的有 4 种方式,分别是:GET(查)、POST(增)、PUT(改)、DELETE(删)。

method 返回的也是一个数组,因此也可以指定多个。如下所示:

@Controller
@RequestMapping(path = "/xttblog")
public class XttblogController {
    // 该方法将同时接收通过GET和POST方式发来的请求
    @RequestMapping(path = "/login", method={RequestMethod.POST,RequestMethod.GET})
    public String login() {
        return "success";
    }
}

@RequestMapping 的 params 属性,该属性表示请求参数,也就是追加在URL上的键值对。看下面的例子:

@Controller
@RequestMapping(path = "/xttblog")
public class XttblogController {
    // 该方法将接收 /xttblog/login 发来的请求,且请求参数必须为 username=xttblog&password=123456
    @RequestMapping(path = "/login", params={"username=xttblog","password=123456"})
    public String login() {
        return "success";
    }
}

@RequestMapping 的 headers 属性,表示请求头中的配置。例如常见的 token,一般都是放在请求头中。headers 属性同样支持多个配置的。

例如,headers="Host=localhost:8080" 则表示只接收本机发来的请求。

@RequestMapping 中的 value 属性还支持占位符。如下用法:

@RequestMapping(value="/{id}", method=RequestMethod.GET)
public String show(@PathVariable("id") Integer id) {
    return "success";
}

show() 方法将可以接收 user/1、user/2、user/3等路径的请求,但是请求的方法必须为 GET,使用 @PathVariable 为应用实现 REST 规范提供了具大的便利条件。

@RequestMapping 的 value 属性还支持非常复杂的正则表达式,但是同样的需要配合 @PathVariable 注解一起使用。

@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
public void handle(@PathVariable String version, @PathVariable String extension) {}

consumes 属性用来限制 ContentType。ContentType 用来告诉服务器当前发送的数据是什么格式。 produces 用来限制 Accept。Accept 用来告诉服务器,客户端能认识哪些格式,最好返回这些格式中的其中一种。

如果我们配置了,consumes={"application/xml","application/json"},produces={"application/xml"} 那么我们就只能接收 application/xml 格式,也只返回 xml 格式。

至此,@RequestMapping 的大多用法都已经解释完了。熟能生巧,大家都用起来吧!