优秀的编程知识分享平台

网站首页 > 技术文章 正文

@RequestMapping注解你真的会用吗

nanyue 2024-07-22 13:56:23 技术文章 8 ℃

昨天说了Spring MVC框架中是如何根据Url找到对应的方法的,实际上就是将@RequestMapping注解封装成了一个RequestMappingInfo对象,然后我就发现@RequestMapping注解中的一些参数。

我们大部分用的都是@RequestMapping中的value或者path属性,但实际上@RequestMapping中可不止这两个属性,今天我们一起来看看。

首先@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 {};

接下来我们分别来了解一下

value和path

这个是最常用的,但其实他是个数组,也就是说我们可以设置多个路径;

由于@RequestMapping也可以写在类上,因此,如果类上是多个路径、方法上也是多个路径,那么我们可以通过任何类路径+任何方法路径访问到此接口

@RequestMapping(value = {"/hh","/ii","jj","kk"})
public String hh(){
    return "hh";
}
//或者是下面这种,效果一样
@RequestMapping(path = {"/hh","/ii","jj","kk"})
public String hh(){
    return "hh";
}

name

这个字段是我最陌生的的一个,这是我在跟踪源码的时候看到的,Spring通过RequestMappingInfoHandlerMethodMappingNamingStrategy来生成name,如果没有指定名字的话,在类上则是所有大写字母,在方法上则是方法名,通过'#'进行拼接,例如:

@RequestMapping(value = {"/demo","/demo1","/demo2"})
@RestController
public class DemoController {
    @RequestMapping(path = {"/hh","/ii","jj","kk"})
    public String hh(){
        return "hh";
    }
}
//则生成的名字是DC#hh

那生成的这个name到底有鸡毛用呢?

其实我也不知道,但是官方给出了解释:

大概就是说它能让你非常方便的在JSP页面上使用它,这么写至少感觉比你这样拼装URL:pageContext.request.contextPath/people/1/addresses/china 显得更好看一点?

哈哈哈哈哈哈,JSP这玩意不早就过时了嘛,难道就是这么玩的?

然后Spring又继续给出了解释:

依赖于Spring标记库(即META-INF/Spring.tld)中申明的mvcUrl函数,此函数的声明如下

<function>
    <description>Helps to prepare a URL to a Spring MVC controller method.</description>
    <name>mvcUrl</name>
    <function-class>org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder</function-class>
    <function-signature>org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder.MethodArgumentBuilder fromMappingName(java.lang.String)</function-signature>
</function>

如果你是其它模版技术(如Thymeleaf)也是很容易自定义一个这样类似的函数的,那么你就依旧可以使用此便捷、强大的功能来帮助你开发。

JSP我早就忘了,Thymeleaf也没具体使用过,对于使用过的小伙伴应该知道是干嘛的吧,这个我就不多说了,知道有这么个东西就行。

method

这个也比较常用,它是请求方式:GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE,通常也可以使用对应的GetMapping,PostMapping等注解代替使用。需要注意的是在@RequestMapping中,method也是一个数组,因此,它也可以指定多种请求方式

@RequestMapping(path = {"/hh","/ii","jj","kk"},method = {RequestMethod.GET,RequestMethod.POST})
public String hh(){
    return "hh";
}

params

这个字段也是一个String数组,它也相当于一个条件,例如:

//我指定了请求中指定了user!=wangpeng
@RequestMapping(value = "/aa",params ={"user!=wangpeng"} )
public String dd(){
    return "dd";
}

当我携带user=wangpeng时,请求不会进入到我当前接口中

当我携带user=wangpeng1时,请求会进入到我当前接口中,也就是说user!=wangpeng会作为条件,当满足条件时会进入到接口中

headers

这个字段也是一个String数组,它也相当于一个条件,与params有类似的效果,例如:

//指定了请求头中参数user!=wangpeng
@RequestMapping(path = {"/ii"},method = {RequestMethod.GET,RequestMethod.POST},headers = "user!=wangpeng")
public String ii(){
    return "ii";
}

当请求头中无参数或者参数user!=wangpeng时,会进入此接口

consumes

这个的作用是指定我们请求中请求体的类型(ContentType),同样的,它也是一个数组,因此可以指定多个类型,例如:

//指定了类型为text/plain,当请求时,如果类型不是text/plain类型,则请求不会进入此接口
@RequestMapping(value = "/aa",consumes = {MediaType.TEXT_PLAIN_VALUE})
public String ff(){
    return "ff";
}

produces

用来限制Accept,Accept是请求头的一种,作用是用来告诉服务器,客户端能认识哪些格式,最好返回这些格式中的其中一种。produces这个元素来缩小请求映射类型的范围。 为了能用请求的媒体类型来产生对象, 你要用到 @RequestMapping 的 produces 元素再结合着 @ResponseBody 注解。

例如:

//我指定了Accept=text/plain,当我请求头中的Accept不是这种类型时,则不会进入到这个方法
@RequestMapping(value = "/aa",consumes = {MediaType.TEXT_PLAIN_VALUE},produces = MediaType.TEXT_PLAIN_VALUE)
public String ff(){
    return "ff";
}

当Accept=text/plain时才会进入到此接口中

最近发表
标签列表